Closed Gujie-Novade closed 5 years ago
The equivalent approach using this package is to set a timeout on the IO HttpClient
like you would when using purely dart:io
, then construct an IOClient
to wrap it as a client from this package.
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...
}
The .timeout
function on Future is unrelated to this package.
If you do want to use future.timeout
you can install a separate error handler for the original future.
Edit: The place where I thought the exception could occur after a .timeout
was incorrect.
The equivalent approach using this package is to set a timeout on the IO
HttpClient
like you would when using purelydart:io
, then construct anIOClient
to wrap it as a client from this package.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... }
The
.timeout
function on Future is unrelated to this package.If you do want to use
future.timeout
you can install a separate error handler for the original future.Future<void> login(String email, String password) async { final body = { 'email': email, 'password': password }; final client = http.Client(); http.Response res; try { res = await client .post( '$url/login', headers: {'Content-Type': 'application/json'}, body: jsonEncode(body)) .catchError((e) { // SocketException would show up here, potentially after the timeout. }) .timeout(const Duration(seconds: 5)); } on TimeoutException catch (e) { // Display an alert, no internet } catch (err) { print(err); return null; } // Do something with the response... }
Is this solution still viable? I am having same error. With or without timeout it throws SocketException when there is no internet and I can not catch it with try catch block. When I try to construct a client it does not accept "ioClient" as a parameter.
My code;
try {
final checkEmail = await http
.get(credentials, headers: {headers}).catchError((error) {
print(error);
}).timeout(Duration(seconds: 5));
print(checkEmail.body);
print(checkEmail.statusCode);
return checkEmail.statusCode == 200 ? "ok" : "Could not validate email.";
} on Exception catch (f) {
print(f.toString());
return "Could not validate email.";
} on Error catch (e) {
print(e.toString());
return "Could not validate email.";
}
With or without timeout it throws SocketException when there is no internet and I can not catch it with try catch block.
Do you have a reliable and minimal reproduction case for this? This isn't the first time I've seen a report of an uncatchable exception but I have never been able to set it up on the VM such that I get an unhandled async exception. Whenever I try this I am able to catch the SocketException
in a try/catch
block.
https://github.com/dart-lang/http/pull/508
With or without timeout it throws SocketException when there is no internet and I can not catch it with try catch block.
Do you have a reliable and minimal reproduction case for this? This isn't the first time I've seen a report of an uncatchable exception but I have never been able to set it up on the VM such that I get an unhandled async exception. Whenever I try this I am able to catch the
SocketException
in atry/catch
block.508
I recorded my issue. In first the device is on airplane mode so it throws directly. Second part I cut and sped up the video. Server is offline and I successfully catch timeout exception. After close to a minute it throws the exception. https://youtu.be/dHUFB6jyE48
After close to a minute it throws the exception.
It looks like the exception can be caught because it's showing up in a try block in your debugger.
I'm looking for help reproducing the case where a SocketException
surfaces and cannot be caught at all.
After close to a minute it throws the exception.
It looks like the exception can be caught because it's showing up in a try block in your debugger.
I'm looking for help reproducing the case where a
SocketException
surfaces and cannot be caught at all.
Sorry if this is a noob question, I am a bit inexperienced. Can you tell me how I can catch it inside of current block?
Still having same issue.
This is my Code:
Future<ComputerModel?> checkIfComputerHasRufSohn(String ip) async {
try {
var response = await http
.get(Uri.http(ip, '/test?test=hi'))
.timeout(const Duration(seconds: 5))
.catchError((error, stacktrace) {
print("catched error");
});
//TODO parse daten
return ComputerModel("Name", ip);
} on SocketException catch (e) {
//print("Caught socketexception: $e");
} on TimeoutException catch (e) {
//print('Caught: $e');
} catch (e) {}
//print('Done');
return null;
}
All exceptions get successfully caught. Only Socket Timeout Exception gets triggered after ~1 Minute and crashes App without being catchable.
@natebosch I too am having this issue that @Binozo et. al. outlined.
I suppose this isn't a huge issue because the first response gives a way around using a client object. That (sans the typo in the code) fixed it for me.
I want to create a login request and set a timeout of 5s.
If I use this code:
In case there is no internet, I will catch the Timeout Exception first. But 15-20s later, there will be another SocketException thrown asynchronously which I cannot catch...
However, if I only use dart.io with this code:
In case of a timeout, the exception will be thrown as a SocketException so I don't have this issue.
BTW, someone already created a question on SO here
So there is a problem with the
.timeout()
function.