I'm having trouble working out how I can catch exceptions from isolates. With the following code, I've tried everything I can think of to handle the error that is thrown from task, but it's still marked as Unhandled exception.
void main() async {
try {
var rp = ReceivePort();
rp.listen((message) {
print(message);
}, one rror: (e) {
print(e);
});
rp.handleError((e) {
print(e);
});
var isolate = await Isolate.spawn(task, rp.sendPort);
isolate.addErrorListener(rp.sendPort);
} catch (e) {
print(e);
}
}
void task(SendPort sp) {
sp.send('hello from isolate');
throw Exception();
}
What am I missing here? I've also tried the following as suggested by an answer below:
void main() async {
try {
var rp = ReceivePort();
rp.listen((message) {
print(message);
}, one rror: (e) {
print('Handling exception');
print(e);
});
await Isolate.spawn(task, rp.sendPort, one rror: rp.sendPort);
} catch (e) {
print(e);
}
}
void task(SendPort sp) {
sp.send('hello from isolate');
throw Exception();
}
CodePudding user response:
I think you have missed an important segment of the documentation for Isolate.spawn:
You can also call the
setErrorsFatal,addOnExitListenerandaddErrorListenermethods on the returned isolate, but unless the isolate was started aspaused, it may already have terminated before those methods can complete.
You issue is that your spawned Isolate has already executed throw Exception() before your isolate.addErrorListener(rp.sendPort); has been executed.
Instead, do something like this to spawn the Isolate as paused and then later resume it:
var isolate = await Isolate.spawn(task, rp.sendPort, paused: true);
isolate.addErrorListener(rp.sendPort);
isolate.resume(isolate.pauseCapability!);
Alternative, you can just give the Isolate your error handler as part of spawning:
var isolate = await Isolate.spawn(task, rp.sendPort, one rror: rp.sendPort);
