dartflutterdart-http

How to catch SocketException using the http library?


This problem has already been pointed out by others (like here). Althought I may have understood the cause, I still haven't found a solution when using the higher-level http library. For example:

import 'package:http/http.dart';

// yes, pwd is String, it's just a test...
Future<Response> login(String user, String pwd) {
  final authHeader = encodeBasicCredentials(user, pwd);
  return get(
    'http://192.168.0.100:8080/login',
    headers: <String, String>{
    HttpHeaders.AUTHORIZATION: authHeader,
    },
  ));
}

I can't find a way to catch a SocketException that is thrown, for example, if the host can't be reached (in my case, wrong host ip). I have tried wrapping the await in try/catch, or using Future.catchError.

This is a stacktrace of the exception:

[ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter ( 4036): SocketException: OS Error: Connection refused, errno = 111, address = 192.168.0.100, port = 35588
E/flutter ( 4036): #0      IOClient.send (package:http/src/io_client.dart:30:23)
E/flutter ( 4036): <asynchronous suspension>
E/flutter ( 4036): #1      BaseClient._sendUnstreamed (package:http/src/base_client.dart:171:38)
E/flutter ( 4036): <asynchronous suspension>
E/flutter ( 4036): #2      BaseClient.get (package:http/src/base_client.dart:34:5)
E/flutter ( 4036): #3      get.<anonymous closure> (package:http/http.dart:47:34)
E/flutter ( 4036): #4      _withClient (package:http/http.dart:167:20)
E/flutter ( 4036): <asynchronous suspension>
E/flutter ( 4036): #5      get (package:http/http.dart:47:3)

Solution

  • You can change login to be async so that you can await the response. That allows you to catch the exception (and, for example, return null instead of the Response).

    Future<Response> login(String user, String pwd) async {
      final String authHeader = encodeBasicCredentials(user, pwd);
      try {
        return await get(
            'http://192.168.0.100:8080/login',
            headers: {
              HttpHeaders.AUTHORIZATION: authHeader,
            },
          );
      } catch (e) {
        print(e);
        return null;
      }
    }