Cannot catch SocketException - sockets

I am trying out Dart and I've been struggling with this for quite a bit now. Calling:
runServer() {
HttpServer.bind(InternetAddress.ANY_IP_V4, 8080)
.then((server) {
server.listen((HttpRequest request) {
request.response.write('Hello, World!');
request.response.close();
});
});
}
Once works like a charm. And then, trying
try {
runServer();
} on Error catch (e) {
print("error");
} on Exception catch(f) {
print("exception");
}
Now I'd expect that if I were to use this try-catch and start listening to the same port more than once, because I'm catching ALL exceptions and ALL errors, the program wouldn't crash. However, after running the code twice, instead of entering any try/catch clause I get:
Uncaut Error: SocketException: Failed to create server socket (OS Error: Only one usage of each socket address (protocol/network address/port) is normally permitted.
While I understand what the error is, I don't understand why doesn't it simply enter the catch Error/Exception clause?

Asynchronous errors can't be caught using try/catch (https://www.dartlang.org/docs/tutorials/futures/) at least unless you are using async/await (https://www.dartlang.org/articles/await-async/)
See also https://github.com/dart-lang/sdk/issues/24278
You can use the done future on the WebSocket object to get that error, e.g.:
import 'dart:async';
import 'dart:io';
main() async {
// Connect to a web socket.
WebSocket socket = await WebSocket.connect('ws://echo.websocket.org');
// Setup listening.
socket.listen((message) {
print('message: $message');
}, onError: (error) {
print('error: $error');
}, onDone: () {
print('socket closed.');
}, cancelOnError: true);
// Add message, and then an error.
socket.add('echo!');
socket.addError(new Exception('error!'));
// Wait for the socket to close.
try {
await socket.done;
print('WebSocket donw');
} catch (error) {
print('WebScoket done with error $error');
}
}

Related

httpClient Request can not catch the error in flutter

here when i try to catch the error when i try to use the request without internet i can not catch the error for dealing with thim.
var httpClient = HTTP.Client();
var request = HTTP.Request("GET", Uri.parse(url));
request.headers.addAll({'Range': 'bytes=$downloadFrom-$downloadUntil'});
var response;
try{
response = httpClient.send(request).catchError((error){ throw error;});
}catch(e){
print("----> " + e.toString());
}
As according to this post: How do I check Internet Connectivity using HTTP requests(Flutter/Dart)?
I quote:
You should surround it with try catch block, like so:
import 'package:http/http.dart' as http;
int timeout = 5;
try {
http.Response response = await http.get('someUrl').
timeout(Duration(seconds: timeout));
if (response.statusCode == 200) {
// do something
} else {
// handle it
}
} on TimeoutException catch (e) {
print('Timeout Error: $e');
} on SocketException catch (e) {
print('Socket Error: $e');
} on Error catch (e) {
print('General Error: $e');
}
Socket exception will be raised immediately if the phone is aware that there is no connectivity (like both WiFi and Data connection are turned off).
Timeout exception will be raised after the given timeout, like if the server takes too long to reply or users connection is very poor etc.
Also don't forget to handle the situation if the response code isn't = 200.

catchError and "try - catch" is not working (async)

My code is trying to communicate using Socket, but I can't seem to catch the exception.
I've tried these things, but they don't work and I get an exception on the IDE.
Socket socket;
try {
socket = await Socket.connect(ip, port);
// Instead of jumping to errorProcess(), the IDE will show an exception here...
} catch(e) {
errorProcess(e);
}
Socket socket = await Socket.connect(ip, port).catchError((e) {
errorProcess(e);
// catchError says we need to return FutureOr<Socket>...
});
How can I catch exceptions?
Try adding SocketException for your try catch statement.
Example Code:
try {} on SocketException catch (e) {
print(e);
} catch (e) {
print(e);
}

Error: DioError [DioErrorType.other]: SocketException: Failed host lookup: not being caught

I am using dio 4.0.2. The problem is that when there is no internet connection(when internet and wifi is not turned on), SocketException: Failed host lookup is not being caught. I checked via interceptor's onError method and I am sure it is sending error from interceptor. But post request is not throwing error for this.
Here is my interceptor on error code:
#override
void onError(DioError err, ErrorInterceptorHandler handler) {
super.onError(err, handler);
}
How can I catch this?
I'm using it like this:
bool _isServerDown(DioError error) {
return (error.error is SocketException) || (error.type == DioErrorType.connectTimeout);
}
#override
Future<void> onError(DioError error, ErrorInterceptorHandler handler) async {
if (_isServerDown(error)) {
Response? response;
try {
response = await tryAnotherUrl(error.requestOptions);
} catch (error) {
if (error is DioError) {
response = error.response;
handler.next(error);
return;
}
}
if (response != null) {
handler.resolve(response);
} else {
handler.next(error);
}
return;
}
Not sure why, but this worked for me:
// add error interceptor to catch all errors
dioBuilder.dio.interceptors.add(
InterceptorsWrapper(
onError: (error, handler) {
// Do stuff here
handler.reject(error); // Added this line to let error propagate outside the interceptor
},
),
);

I want to handle denying permission error

I use Flutter_blue package
When I deny access to bluetooth there is an error I can't handle. This is what shows:
This is how my code looks like:
scan() {
// Start scanning
try {
blue.startScan(timeout: const Duration(seconds: 4));
} on Exception catch (e) {
log(e.toString());
} catch (e) {
log(e.toString());
}
}
I want to handle denying permission to bluetooth. Can't handle exception error
If you use method startScan which returns a Future you can use catchError method on Future class:
blue.startScan().catchError((error) {
// handle errors here
});
If you use method scan which returns a Stream you can handle errors specifying onError parameter when calling listen method:
blue.scan(timeout: const Duration(seconds: 4)).listen((event) {
// here comes data
}, onError: (Object error){
// handle an error here
});
You can read more about the listen method here.
OR
You can use handleError method on Stream object:
blue.scan(timeout: const Duration(seconds: 4))
.handleError((error) => print('Exception caught for $error')) // handle the error
.listen((event) {
// here comes data
});

How to handle socket disconnects in Dart?

I'm using Dart 1.8.5 on server.
I want to implement TCP Socket Server that listens to incoming connections, sends some data to every client and stops to generate data when client disconnects.
Here is the sample code
void main() {
ServerSocket.bind(
InternetAddress.ANY_IP_V4,
9000).then((ServerSocket server) {
runZoned(() {
server.listen(handleClient);
}, onError: (e) {
print('Server error: $e');
});
});
}
void handleClient(Socket client) {
client.done.then((_) {
print('Stop sending');
});
print('Send data');
}
This code accepts connections and prints "Send data". But it will never print "Stop sending" even if client was gone.
The question is: how to catch client disconnect in listener?
A Socket is bidirectional, i.e. it has an input stream and an output sink. The Future returned by done is called when the output sink is closed by calling Socket.close().
If you want to be notified when the input stream closes try using Socket.drain() instead.
See the example below. You can test it with telnet. When you connect to the server it will send the string "Send." every second. When you close telnet (ctrl-], and then type close). The server will print "Stop.".
import 'dart:io';
import 'dart:async';
void handleClient(Socket socket) {
// Send a string to the client every second.
var timer = new Timer.periodic(
new Duration(seconds: 1),
(_) => socket.writeln('Send.'));
// Wait for the client to disconnect, stop the timer, and close the
// output sink of the socket.
socket.drain().then((_) {
print('Stop.');
timer.cancel();
socket.close();
});
}
void main() {
ServerSocket.bind(
InternetAddress.ANY_IP_V4,
9000).then((ServerSocket server) {
runZoned(() {
server.listen(handleClient);
}, onError: (e) {
print('Server error: $e');
});
});
}