From 5a52ad6dbdba7ecba5ce449d65add5c190324e12 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 18 Mar 2022 11:30:21 -0700 Subject: [PATCH] [framework] Remove danger zone (#100246) --- .../lib/src/painting/image_provider.dart | 39 +++++---------- .../test/painting/image_provider_test.dart | 49 ------------------- 2 files changed, 11 insertions(+), 77 deletions(-) diff --git a/packages/flutter/lib/src/painting/image_provider.dart b/packages/flutter/lib/src/painting/image_provider.dart index d628c9652c..0d5f1cef38 100644 --- a/packages/flutter/lib/src/painting/image_provider.dart +++ b/packages/flutter/lib/src/painting/image_provider.dart @@ -435,38 +435,21 @@ abstract class ImageProvider { 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 key; + Future key; + try { + key = obtainKey(configuration); + } catch (error, stackTrace) { + handleError(error, stackTrace); + return; + } + key.then((T key) { + obtainedKey = key; try { - key = obtainKey(configuration); + successCallback(key, handleError); } catch (error, stackTrace) { handleError(error, stackTrace); - return; } - key.then((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]. diff --git a/packages/flutter/test/painting/image_provider_test.dart b/packages/flutter/test/painting/image_provider_test.dart index 5d1087a466..d00a750654 100644 --- a/packages/flutter/test/painting/image_provider_test.dart +++ b/packages/flutter/test/painting/image_provider_test.dart @@ -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 caughtError = Completer(); - 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 caughtError = Completer(); - final Completer onErrorCompleter = Completer(); - 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 error = Completer(); FlutterError.onError = (FlutterErrorDetails details) {