[framework] Remove danger zone (#100246)
This commit is contained in:
parent
0adf9671f8
commit
5a52ad6dbd
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user