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)
A SocketException is thrown by the Socket and Dns classes when an error occurs with the network. The parameterless constructor for the SocketException class sets the ErrorCode property to the last operating system socket error that occurred.
The try / on / catch Blocks The on block is used when the exception type needs to be specified. The catch block is used when the handler needs the exception object. The try block must be followed by either exactly one on / catch block or one finally block (or one of both).
This SocketException occurs on the server-side when the client closed the socket connection before the response could be returned over the socket. For example, by quitting the browser before the response was retrieved. Connection reset simply means that a TCP RST was received.
You can check the type of the exception and treat it accordingly something like:
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) {
if(e is SocketException){
//treat SocketException
print("Socket exception: ${e.toString()}");
}
else if(e is TimeoutException){
//treat TimeoutException
print("Timeout exception: ${e.toString()}");
}
else print("Unhandled exception: ${e.toString()}");
}
}
Probly better off making an error handler lib, so you can just call a function like handleException(e);
on the catch block.
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With