@@ -21,6 +21,8 @@ class ParentPortClient implements PortClient {
21
21
final ReceivePort _receivePort = ReceivePort ();
22
22
final ReceivePort _errorPort = ReceivePort ();
23
23
bool closed = false ;
24
+ Object ? _closeError;
25
+ String ? _isolateDebugName;
24
26
int _nextId = 1 ;
25
27
26
28
Map <int , Completer <Object ?>> handlers = HashMap ();
@@ -59,33 +61,34 @@ class ParentPortClient implements PortClient {
59
61
close ();
60
62
});
61
63
_errorPort.listen ((message) {
62
- var [error, stackTrace] = message;
64
+ final [error, stackTraceString] = message;
65
+ final stackTrace = stackTraceString == null
66
+ ? null
67
+ : StackTrace .fromString (stackTraceString);
63
68
if (! initCompleter.isCompleted) {
64
- if (stackTrace == null ) {
65
- initCompleter.completeError (error);
66
- } else {
67
- initCompleter.completeError (error, StackTrace .fromString (stackTrace));
68
- }
69
+ initCompleter.completeError (error, stackTrace);
69
70
}
71
+ _close (IsolateError (cause: error, isolateDebugName: _isolateDebugName),
72
+ stackTrace);
70
73
});
71
74
}
72
75
73
76
Future <void > get ready async {
74
77
await sendPortFuture;
75
78
}
76
79
77
- void _cancelAll (Object error) {
80
+ void _cancelAll (Object error, [ StackTrace ? stackTrace] ) {
78
81
var handlers = this .handlers;
79
82
this .handlers = {};
80
83
for (var message in handlers.values) {
81
- message.completeError (error);
84
+ message.completeError (error, stackTrace );
82
85
}
83
86
}
84
87
85
88
@override
86
89
Future <T > post <T >(Object message) async {
87
90
if (closed) {
88
- throw ClosedException ();
91
+ throw _closeError ?? const ClosedException ();
89
92
}
90
93
var completer = Completer <T >.sync ();
91
94
var id = _nextId++ ;
@@ -98,7 +101,7 @@ class ParentPortClient implements PortClient {
98
101
@override
99
102
void fire (Object message) async {
100
103
if (closed) {
101
- throw ClosedException ();
104
+ throw _closeError ?? ClosedException ();
102
105
}
103
106
final port = sendPort ?? await sendPortFuture;
104
107
port.send (_FireMessage (message));
@@ -108,17 +111,27 @@ class ParentPortClient implements PortClient {
108
111
return RequestPortServer (_receivePort.sendPort);
109
112
}
110
113
111
- void close () async {
114
+ void _close ([ Object ? error, StackTrace ? stackTrace]) {
112
115
if (! closed) {
113
116
closed = true ;
114
117
115
118
_receivePort.close ();
116
119
_errorPort.close ();
117
- _cancelAll (const ClosedException ());
120
+ if (error == null ) {
121
+ _cancelAll (const ClosedException ());
122
+ } else {
123
+ _closeError = error;
124
+ _cancelAll (error, stackTrace);
125
+ }
118
126
}
119
127
}
120
128
129
+ void close () {
130
+ _close ();
131
+ }
132
+
121
133
tieToIsolate (Isolate isolate) {
134
+ _isolateDebugName = isolate.debugName;
122
135
isolate.addErrorListener (_errorPort.sendPort);
123
136
isolate.addOnExitListener (_receivePort.sendPort, response: _closeMessage);
124
137
}
@@ -274,6 +287,27 @@ class _RequestMessage {
274
287
275
288
class ClosedException implements Exception {
276
289
const ClosedException ();
290
+
291
+ @override
292
+ String toString () {
293
+ return 'ClosedException' ;
294
+ }
295
+ }
296
+
297
+ class IsolateError extends Error {
298
+ final Object cause;
299
+ final String ? isolateDebugName;
300
+
301
+ IsolateError ({required this .cause, this .isolateDebugName});
302
+
303
+ @override
304
+ String toString () {
305
+ if (isolateDebugName != null ) {
306
+ return 'IsolateError in $isolateDebugName : $cause ' ;
307
+ } else {
308
+ return 'IsolateError: $cause ' ;
309
+ }
310
+ }
277
311
}
278
312
279
313
class _PortChannelResult <T > {
0 commit comments