'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 1:[1]
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;
}
}
Solution 2:[2]
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.
Solution 3:[3]
SocketException on http
try {
} on SocketException {
}
Solution 4:[4]
One simple way to catch the error is to call a method on the get method by using the catch error argument like so. This method of the get method can catch others types of errors, not only the socket exception. Look at the code below for more
import 'package:http/http.dart';
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,
},
).catchError(error){
//you can now do your error handling in this block
});
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Richard Heap |
Solution 2 | Fabio Dias |
Solution 3 | BIS Tech |
Solution 4 | Ransford Owusu |