http
http copied to clipboard
Flutter try catch can't catch SocketException ( Exception has occurred. SocketException (SocketException: OS Error: No route to host, errno = 113)
Flutter App crashed after getting this exception
Exception has occurred. SocketException (SocketException: OS Error: No route to host, errno = 113, address = 10.162.18.32, port = 60208)
THE same URL is accessible from the testing phone, Postman. also tried with
try {
} on SocketException {
}
Still, Exception is not handled.
Future<List<Post>> getPosts() async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
print(prefs.get(key));
final value = prefs.get(key) ?? 0;
Map<String, String> headers = {
"Accept": "application/json",
"Authorization": "Bearer $value"
};
print("before res");
var responseJson;
try {
print("ins try get url " + host + "posts");
final response = await http.get(host + "posts",
headers: headers); //Exception on this line
print("final try");
responseJson = _response(response);
} catch (e) {
print(e);
return null;
//throw FetchDataException('No Internet connection');
}
// if (res.statusCode == 200) {
List<dynamic> body = responseJson;
List<Post> posts = body
.map(
(dynamic item) => Post.fromJson(item),
)
.toList();
return posts;
// } else {
// print('A network error occurred');
// //throw "Can't get posts.";
// }
}
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.0.2, on Microsoft Windows [Version 10.0.18363.836], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.1)
[√] Chrome - develop for the web
[√] Android Studio (version 4.1.0)
[√] VS Code (version 1.54.3)
[√] Connected device (2 available)
• No issues found!
PS C:\Users\nicalp\AndroidStudioProjects\vikasapp> flutter --version
Flutter 2.0.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 8962f6dc68 (11 days ago) • 2021-03-11 13:22:20 -0800
Engine • revision 5d8bf811b3
Screenshots
https://i.ibb.co/VVHV3Sr/image.png
https://i.ibb.co/GMRZZ21/image.png
same here:
flutter: SocketException: Connection failed (OS Error: Network is unreachable, errno = 51), address = 192.168.4.1, port = 80
though it's accessible from my phone's google chrome.
[✓] Flutter (Channel master, 2.1.0-13.0.pre.294, on macOS 11.2.3 20D91 darwin-x64, locale en)
• Flutter version 2.1.0-13.0.pre.294 at /Users/shalaby/Developer/flutter
• Framework revision a603714610 (25 hours ago), 2021-03-28 03:54:02 -0700
• Engine revision b5e15d055d
• Dart version 2.13.0 (build 2.13.0-162.0.dev)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
• Android SDK at /Users/shalaby/Library/Android/sdk
• Platform android-30, build-tools 30.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 12.4, Build version 12D4e
• CocoaPods version 1.10.1
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 4.1)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
[✓] VS Code (version 1.54.3)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.20.0
[✓] Connected device (2 available)
• Mahmoud’s iPhone (mobile) • 00008030-00037981012A802E • ios • iOS 14.4.2
• Chrome (web) • chrome • web-javascript • Google Chrome 89.0.4389.90
• No issues found!
tested on stable, dev, and master channels. using latest package release
I also had a similar problem in case the server still hasn't started. App crash right at this line of code
例外が発生しました
SocketException (SocketException: OS Error: Connection refused, errno = 111, address = 192.168.xxx.xxx, port = xxx)
flutter doctor
[✓] Flutter (Channel stable, 2.0.3, on macOS 11.2.3 20D91 darwin-x64, locale ja-JP)
• Flutter version 2.0.3 at $HOME/develop/flutter
• Framework revision 4d7946a68d (11 days ago), 2021-03-18 17:24:33 -0700
• Engine revision 3459eb2436
• Dart version 2.12.2
pubspec.yaml
http: ^0.13.1
If it could catch the exception and proceed logically instead of crashing the app then maybe better.
If it could catch the exception and proceed logically instead of crashing the app then maybe better.
so is there is a workaround?
@EgHubs how did it workaround??
@EgHubs how did it workaround??
Iam asking if you solved it.
I still haven't solved it yet 😅
+1
I got a similar issue when using http.post
and my test server is not running.
At least for my issue, it seems like IOClient
is only catching HttpException
s but somewhere in HttpClient.openUrl
a SocketException
can be thrown.
But I use some async code to catch the error and don't have issues with this; maybe worth trying for others with issues
return http
.post(
cloudUri,
headers: { 'Content-Type': 'application/json' },
body: jsonString,
)
.then((response) {
if (response.statusCode == 200) {
_log.fine('event sent');
return Future.value();
} else {
_log.info('event could not be sent, status ${response.statusCode}');
return Future.error(
'http error code ${response.statusCode.toString()}');
}
}).onError((error, stackTrace) {
_log.warning('could not send event, error ', error);
// catch error here
return Future.value();
});
I also encountered this with a socket exception. Quite frustrating.
SocketException: OS Error: Connection timed out, errno = 110, address = 192.168.0.1, port = 37694
edit:
I should clarify that I'm not just getting a random socket exception -- the method I'm calling that contains my http.get
method is throwing a socket exception and then exiting the method without falling to any catch
blocks.
Like flo80 said, this happens when the server in question is offline, meaning no response is possible.
I have the same problem, but it seems to be a problem with flutter instead.
From the debugger it seems that exception is coming from the dart:io package
Can someone provide a complete minimal reproduction case and instructions to see this behavior?
I have not been able to locally reproduce a case where using try
, await
, and catch
doesn't catch the exception. When I run in an ios simulator the SocketException
gets caught by exactly the catch
block I'd expect.
i have the same error with subdomains in localhost ( http://sub.localhost:80/example ) . But i have not in ( http://localhost:80 ), help me please.
Flutter try catch can't catch SocketException ( Exception has occurred. SocketException (SocketException: OS Error: No route to host, errno = 8)
i have the same error
As above, we still need a reproduction case that we can debug.
I solved the problem, when I use the package in localhost a vhost must be configured, that solved the problem. in my case use xampp with laravel in mac os.
example: in the terminal write "vim /etc/hosts" to edit vhost
127.0.0.1 subdomain.localhost
This issue is hard to spot, at least in my case, i only know it is happening when i see the crashlytics dashboard.
Crashlytics report
Non-fatal Exception: FlutterError
SocketException: Connection failed (OS Error: No route to host, errno = 65), address = dundermifflin.com, port = 443. Error thrown null.
Non-fatal Exception: FlutterError
0 ??? 0x0 _HttpClient.openUrl (dart:_http)
1 ??? 0x0 IOClient.send + 30 (io_client.dart:30)
2 ??? 0x0 BaseClient._sendUnstreamed + 93 (base_client.dart:93)
3 ??? 0x0 BaseClient.post + 32 (base_client.dart:32)
4 ??? 0x0 RestServiceBase.postData + 63 (rest_service_base.dart:63)
5 ??? 0x0 UserRestService.getNewNotifications + 206 (user_rest_service.dart:206)
6 ??? 0x0 LandingScreenStateProvider._pollNotifications + 298 (landing_state_provider.dart:298)
My code
@protected
Future<Map<String, dynamic>> getData(Uri url) async {
http.Response result;
final httpClientInstance = new httpClient.IOClient();
try {
result = await httpClientInstance.get(url, headers: this._getHeaders());
} catch (ex, s) {
// process error
} finally {
httpClientInstance.close();
}
if (await _processResponseForTokenRefreshment(result)) {
return getData(url);
}
return this._processResponse(result);
}
I came across the same issue today. It seems to be an error thrown inside the http package itself outside of the async/await context, so it cannot be handled by try-catch..
Looks like the issue is thrown in io_client.dart
line 30:
var ioRequest = (await _inner!.openUrl(request.method, request.url))
Any progress on this?
Code to reproduce: https://github.com/dart-lang/http/pull/508#issuecomment-938508385
Any progress here?
Also having this issue. This bug is cluttering log outputs.
I had the same issue, I'm not sure if my catch was only catching http errors but when I changed my try{} catch(e){}
to
try{ } on Exception catch (e) { }
it seems to work
See this issue
We need to use the onError callback as well.
try {
socket = socket.connect().onError((e){
throw e as SocketException;
})
} catch (e) {
// Now it will finally get in the handler
}
Also, I programatically close the socket
await _socket?.close().onError((error, stackTrace) => null);
If I omit the onError, I get uncaught SocketExceptions. The weird thing is that I tried to add some logic in the onError (except returning null) and the app would crash. The annoying thing is that I can't properly debug, since it only happens on physical iOS devices when the app has been suspended by the OS.
Soo.... No clue what's going on here
Calling the error throwing function inside runZonedGuarded helped me catch the error.
Now good luck with WebSocketChannel.connect()
, which isn't async and seems to wrap HTTPClient...
In my case, removing the timeout duration specification seems to have fixed the error.
I changed somthing like this:
import 'package:http/http.dart' as http;
// ...
response = await http.post(
Uri.http(theUri),
headers: theHeaders,
body: theBody,
).timeout(Duration(seconds: theTimeout));
into somenthing like this:
import 'package:http/http.dart' as http;
// ...
response = await http.post(
Uri.http(theUri),
headers: theHeaders,
body: theBody,
);
I'm also experiencing this issue. And like @matcaste using a timeout on the http Future (get-Requests in my case) is the issue.
I'm sending multiple get requests, and it seems to me that with a timeout shorter than this packages internal timout you will run into this issue. Probably because the code execution has moved on already and the catch statement is no longer actively looking for something to catch.
EDIT: to clarify, this is indeed not a bug in http package, but a bug in Dart and Futures. Or my and others limited knowledge of Futures and not knowing how to correctly handle this behaviour. Here is a minimal reproducable example:
Future<void> main() async {
try {
var resultFuture = complexAsyncTask();
var timeoutFuture = resultFuture.timeout(const Duration(seconds: 1), onTimeout: () {
print("timeout");
return "timeout return";
});
final String result = await timeoutFuture;
print(result);
} catch (e) {
print("catched exception: $e");
}
}
Future<String> complexAsyncTask() => _withTryFinallyAwait(() => _complexAsyncTask());
Future<T> _withTryFinallyAwait<T>(Future<T> Function() fn) async {
try {
return await fn();
} finally {
print("finally");
}
}
Future<String> _complexAsyncTask() async {
return await Future.delayed(const Duration(seconds: 2), () {
throw Exception('exception thrown after 2 seconds delay');
//return "success";
});
}
If we await resultFuture (like in the example code), we have to wait for 2 seconds and the exception will be catched correctly. However, if we instead await the timeoutFuture (switch the comment to await resultFuture) we only wait for 1 second until the timeout happens and thrown Exception does NOT get catched.
Anybody knows how to wait only for the timeout but still catch an exception thrown in the async task ?
Any update here?
+1
Hi, I got the same error and I fixed it by using
runZonedGuarded
here's my code
Future<Response?> post(String path, dynamic parameter) async =>
runZonedGuarded<Future<Response?>>(() async {
return await client.post(path,
data: json.encode(parameter),
options: Options(
headers: headers
..addAll(<String, String>{
'Authorization': await localData.read(accessTokenName) ?? ''
}),
));
}, (error, stack) {
throw Exception('SERVER DOWN');
});
https://api.flutter.dev/flutter/dart-async/runZonedGuarded.html
for more explanation https://www.youtube.com/watch?v=pHpvfaanrbw&list=PLJbE2Yu2zumC4_aB75G2lQ-tAZlqIOGVx&index=3
BLESS YOU!!! @bkan36
thanks @CrownedComedian. Do you have any mistakes when your server return a fail response like 400, 403... etc ?? After I've solved the socket exception uncaught I was trouble shooting another issue when my back-end return a failed response, So I tried to solve the problem, but unfortunately I wasn't successful, then I back to the version that worked and this code no longer works -___- (this weird issue has tired me);
At the moment I gave up and will continue to develop other features....
My situation is a bit different then that mentioned in this thread -- I was lucky to have even stumbled upon it. I've been working on an app to run provisioning code for my ESP device. Using Flutter's http package to communicate to the device abruptly ended my connection for some unknown reason, so I'm using platform specific code which seems to handle things. The exception I was getting was:
java.net.SocketException: socket failed: ENONET (Machine is not on the network)
And the basic gist of my Flutter/Dart code now includes:
Future<void> _runInZonedGuard() async {
try {
await _platform.invokeMethod(methodName, input).then((results) => {
// cry happy tears
}).onError((error, stack) => {
// platform code called .error()
});
} catch (e) {
// platform code threw exception
}
}
runZonedGuarded(() => _runInZonedGuard(), (error, stack) {
// I haven't gotten this to execute but it still works just fine
});
Then my platform code has the normal .setMethodCallHandler() with a switch statement in it that will run a call to my ESP device on a background thread via a Handler with a listener that will return .success() or .error() as usual. The SocketException was not being caught (even though other exceptions were) until I added your suggested code. Not sure if that answers your question, but maybe something you can try. Hope it helps! @bkan36