Unverified Commit 5a52ad6d authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[framework] Remove danger zone (#100246)

parent 0adf9671
......@@ -435,38 +435,21 @@ abstract class ImageProvider<T extends Object> {
didError = true;
}
// If an error is added to a synchronous completer before a listener has been
// added, it can throw an error both into the zone and up the stack. Thus, it
// looks like the error has been caught, but it is in fact also bubbling to the
// zone. Since we cannot prevent all usage of Completer.sync here, or rather
// that changing them would be too breaking, we instead hook into the same
// zone mechanism to intercept the uncaught error and deliver it to the
// image stream's error handler. Note that these errors may be duplicated,
// hence the need for the `didError` flag.
final Zone dangerZone = Zone.current.fork(
specification: ZoneSpecification(
handleUncaughtError: (Zone zone, ZoneDelegate delegate, Zone parent, Object error, StackTrace stackTrace) {
handleError(error, stackTrace);
},
),
);
dangerZone.runGuarded(() {
Future<T> key;
Future<T> key;
try {
key = obtainKey(configuration);
} catch (error, stackTrace) {
handleError(error, stackTrace);
return;
}
key.then<void>((T key) {
obtainedKey = key;
try {
key = obtainKey(configuration);
successCallback(key, handleError);
} catch (error, stackTrace) {
handleError(error, stackTrace);
return;
}
key.then<void>((T key) {
obtainedKey = key;
try {
successCallback(key, handleError);
} catch (error, stackTrace) {
handleError(error, stackTrace);
}
}).catchError(handleError);
});
}).catchError(handleError);
}
/// Called by [resolve] with the key returned by [obtainKey].
......
......@@ -57,55 +57,6 @@ void main() {
expect(await caughtError.future, true);
});
test('resolve sync errors will be caught', () async {
bool uncaught = false;
final Zone testZone = Zone.current.fork(specification: ZoneSpecification(
handleUncaughtError: (Zone zone, ZoneDelegate zoneDelegate, Zone parent, Object error, StackTrace stackTrace) {
uncaught = true;
},
));
await testZone.run(() async {
final ImageProvider imageProvider = LoadErrorImageProvider();
final Completer<bool> caughtError = Completer<bool>();
FlutterError.onError = (FlutterErrorDetails details) {
throw Error();
};
final ImageStream result = imageProvider.resolve(ImageConfiguration.empty);
result.addListener(ImageStreamListener((ImageInfo info, bool syncCall) {
}, onError: (dynamic error, StackTrace? stackTrace) {
caughtError.complete(true);
}));
expect(await caughtError.future, true);
});
expect(uncaught, false);
});
test('resolve errors in the completer will be caught', () async {
bool uncaught = false;
final Zone testZone = Zone.current.fork(specification: ZoneSpecification(
handleUncaughtError: (Zone zone, ZoneDelegate zoneDelegate, Zone parent, Object error, StackTrace stackTrace) {
uncaught = true;
},
));
await testZone.run(() async {
final ImageProvider imageProvider = LoadErrorCompleterImageProvider();
final Completer<bool> caughtError = Completer<bool>();
final Completer<bool> onErrorCompleter = Completer<bool>();
FlutterError.onError = (FlutterErrorDetails details) {
onErrorCompleter.complete(true);
throw Error();
};
final ImageStream result = imageProvider.resolve(ImageConfiguration.empty);
result.addListener(ImageStreamListener((ImageInfo info, bool syncCall) {
}, onError: (dynamic error, StackTrace? stackTrace) {
caughtError.complete(true);
}));
expect(await caughtError.future, true);
expect(await onErrorCompleter.future, true);
});
expect(uncaught, false);
});
test('File image with empty file throws expected error and evicts from cache', () async {
final Completer<StateError> error = Completer<StateError>();
FlutterError.onError = (FlutterErrorDetails details) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment