4

I use simple method to get some data from internet 'http get request' :

     `Future<UserModel> getUser(int userId) async {
       UserModel user;
       try {
            final response = await http.get(
             "$_baseUrl/users/$userId",
           )
             .timeout(Duration(seconds: 5))

            ;
         user = userModelFromJson(response.body);
       return user;
      } on TimeoutException catch (e) {
       print('$e in authentication service');
     throw e;
      } on SocketException catch (e) {
     print('$e in authentication service');
     throw e;
     } catch (e) {
     print('$e in authentication service');
    throw e;
      }
      }` 

but when i have no internet connection it shows me that error :

 `Exception has occurred.
    SocketException (SocketException: Failed host lookup: 
    'jsonplaceholder.typicode.com' (OS Error: No address associated with 
    hostname, errno = 7))`

whenever i remove the .timeout(Duration(seconds:5)) the code works perfectly , but the socket exception is caught after long time (15-20)seconds to show that there is no internet connection that's why i used timeout, i tried to use multiple packages (http middleware ,http helper ,retry) , i tried to use http.client and close it in finally block and the same error occurred and the app crashes

the image shows the error when the socket exception is thrown and unhandled

it catches the timeout exception as expected but then after another 10-15 seconds it throws an handled socket exception ,why it throws this socket exception and what can i do to avoid this?

kaarimtareek
  • 451
  • 3
  • 10
  • But are you able to actually catch the exception in your try / catch? It seems I have the same error as you but for me, the error is only caught by VSCode (as per the image you linked) – Gpack Oct 09 '19 at 08:19
  • @Gpack is right try your code at android studio it will work – Miki Mar 07 '21 at 04:16

2 Answers2

1

If you want to implement a timeout with the http package, here is how it can be done:

import 'dart:io';

import 'package:http/http.dart' as http;
import 'package:http/io_client.dart' as http;

Future<void> login(String email, String password) async {
    final ioClient = HttpClient();
    client.connectionTimeout = const Duration(seconds: 5);
    final body = { 'email': email, 'password': password };
    final client = http.IOClient(ioClient);
    http.Response res;
    try {
      res = await client
        .post(
          '$url/login',
          headers: {'Content-Type': 'application/json'},
          body: jsonEncode(body));
    } on SocketException catch (e) {
      // Display an alert, no internet
    } catch (err) {
      print(err);
      return null;
    }

    // Do something with the response...
}
Gpack
  • 1,878
  • 3
  • 18
  • 45
-1

You should consider using the HTTP package https://pub.dev/packages/http as it helps cleanup your code an helps with error handling.

Here's an example of a GET request using the package :

await http.get(url).then((response) async {
 // DO SOMETHING HERE
});

response.body is your data. response.statusCode is your http status code (200, 404, 500, etc.)

https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

and here's a post request with data :

var data = {
      "dataset1": {
        "key1": "value",
        "key2": "value",
      },
    };
await http.post(url,
  body: jsonEncode(data),
  headers: {'content-type': 'application/json'}).then((response) async {
    // DO SOMETHING HERE
});