Unverified Commit 8998167d authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Make FlutterErrorDetails.exception non-nullable as documented (#67364)

parent 1271447b
...@@ -390,20 +390,20 @@ class FlutterErrorDetails with Diagnosticable { ...@@ -390,20 +390,20 @@ class FlutterErrorDetails with Diagnosticable {
/// their default values. (`throw null` results in a /// their default values. (`throw null` results in a
/// [NullThrownError] exception.) /// [NullThrownError] exception.)
const FlutterErrorDetails({ const FlutterErrorDetails({
this.exception, required this.exception,
this.stack, this.stack,
this.library = 'Flutter framework', this.library = 'Flutter framework',
this.context, this.context,
this.stackFilter, this.stackFilter,
this.informationCollector, this.informationCollector,
this.silent = false, this.silent = false,
}); }) : assert(exception != null);
/// Creates a copy of the error details but with the given fields replaced /// Creates a copy of the error details but with the given fields replaced
/// with new values. /// with new values.
FlutterErrorDetails copyWith({ FlutterErrorDetails copyWith({
DiagnosticsNode? context, DiagnosticsNode? context,
dynamic exception, Object? exception,
InformationCollector? informationCollector, InformationCollector? informationCollector,
String? library, String? library,
bool? silent, bool? silent,
...@@ -437,7 +437,7 @@ class FlutterErrorDetails with Diagnosticable { ...@@ -437,7 +437,7 @@ class FlutterErrorDetails with Diagnosticable {
/// The exception. Often this will be an [AssertionError], maybe specifically /// The exception. Often this will be an [AssertionError], maybe specifically
/// a [FlutterError]. However, this could be any value at all. /// a [FlutterError]. However, this could be any value at all.
final dynamic exception; final Object exception;
/// The stack trace from where the [exception] was thrown (as opposed to where /// The stack trace from where the [exception] was thrown (as opposed to where
/// it was caught). /// it was caught).
...@@ -552,7 +552,7 @@ class FlutterErrorDetails with Diagnosticable { ...@@ -552,7 +552,7 @@ class FlutterErrorDetails with Diagnosticable {
// some code snippets. This leads to ugly messages. To avoid this, we move // some code snippets. This leads to ugly messages. To avoid this, we move
// the assertion message up to before the code snippets, separated by a // the assertion message up to before the code snippets, separated by a
// newline, if we recognize that format is being used. // newline, if we recognize that format is being used.
final Object? message = exception.message; final Object? message = (exception as AssertionError).message;
final String fullMessage = exception.toString(); final String fullMessage = exception.toString();
if (message is String && message != fullMessage) { if (message is String && message != fullMessage) {
if (fullMessage.length > message.length) { if (fullMessage.length > message.length) {
...@@ -586,8 +586,9 @@ class FlutterErrorDetails with Diagnosticable { ...@@ -586,8 +586,9 @@ class FlutterErrorDetails with Diagnosticable {
} }
Diagnosticable? _exceptionToDiagnosticable() { Diagnosticable? _exceptionToDiagnosticable() {
final Object exception = this.exception;
if (exception is FlutterError) { if (exception is FlutterError) {
return exception as FlutterError; return exception;
} }
if (exception is AssertionError && exception.message is FlutterError) { if (exception is AssertionError && exception.message is FlutterError) {
return exception.message as FlutterError; return exception.message as FlutterError;
......
...@@ -539,7 +539,7 @@ abstract class BindingBase { ...@@ -539,7 +539,7 @@ abstract class BindingBase {
return Future<void>.delayed(Duration.zero); return Future<void>.delayed(Duration.zero);
}); });
dynamic caughtException; Object? caughtException;
StackTrace? caughtStack; StackTrace? caughtStack;
late Map<String, dynamic> result; late Map<String, dynamic> result;
try { try {
......
...@@ -432,7 +432,7 @@ class FlutterErrorDetailsForPointerEventDispatcher extends FlutterErrorDetails { ...@@ -432,7 +432,7 @@ class FlutterErrorDetailsForPointerEventDispatcher extends FlutterErrorDetails {
/// The gesture library calls this constructor when catching an exception /// The gesture library calls this constructor when catching an exception
/// that will subsequently be reported using [FlutterError.onError]. /// that will subsequently be reported using [FlutterError.onError].
const FlutterErrorDetailsForPointerEventDispatcher({ const FlutterErrorDetailsForPointerEventDispatcher({
dynamic exception, required Object exception,
StackTrace? stack, StackTrace? stack,
String? library, String? library,
DiagnosticsNode? context, DiagnosticsNode? context,
......
...@@ -22,7 +22,7 @@ import 'image_stream.dart'; ...@@ -22,7 +22,7 @@ import 'image_stream.dart';
typedef _KeyAndErrorHandlerCallback<T> = void Function(T key, ImageErrorListener handleError); typedef _KeyAndErrorHandlerCallback<T> = void Function(T key, ImageErrorListener handleError);
/// Signature used for error handling by [_createErrorHandlerAndKey]. /// Signature used for error handling by [_createErrorHandlerAndKey].
typedef _AsyncKeyErrorHandler<T> = Future<void> Function(T key, dynamic exception, StackTrace? stack); typedef _AsyncKeyErrorHandler<T> = Future<void> Function(T key, Object exception, StackTrace? stack);
/// Configuration information passed to the [ImageProvider.resolve] method to /// Configuration information passed to the [ImageProvider.resolve] method to
/// select a specific image. /// select a specific image.
...@@ -335,7 +335,7 @@ abstract class ImageProvider<T extends Object> { ...@@ -335,7 +335,7 @@ abstract class ImageProvider<T extends Object> {
(T key, ImageErrorListener errorHandler) { (T key, ImageErrorListener errorHandler) {
resolveStreamForKey(configuration, stream, key, errorHandler); resolveStreamForKey(configuration, stream, key, errorHandler);
}, },
(T? key, dynamic exception, StackTrace? stack) async { (T? key, Object exception, StackTrace? stack) async {
await null; // wait an event turn in case a listener has been added to the image stream. await null; // wait an event turn in case a listener has been added to the image stream.
final _ErrorImageCompleter imageCompleter = _ErrorImageCompleter(); final _ErrorImageCompleter imageCompleter = _ErrorImageCompleter();
stream.setCompleter(imageCompleter); stream.setCompleter(imageCompleter);
...@@ -391,7 +391,7 @@ abstract class ImageProvider<T extends Object> { ...@@ -391,7 +391,7 @@ abstract class ImageProvider<T extends Object> {
(T key, ImageErrorListener innerHandleError) { (T key, ImageErrorListener innerHandleError) {
completer.complete(PaintingBinding.instance!.imageCache!.statusForKey(key)); completer.complete(PaintingBinding.instance!.imageCache!.statusForKey(key));
}, },
(T? key, dynamic exception, StackTrace? stack) async { (T? key, Object exception, StackTrace? stack) async {
if (handleError != null) { if (handleError != null) {
handleError(exception, stack); handleError(exception, stack);
} else { } else {
...@@ -427,7 +427,7 @@ abstract class ImageProvider<T extends Object> { ...@@ -427,7 +427,7 @@ abstract class ImageProvider<T extends Object> {
) { ) {
T? obtainedKey; T? obtainedKey;
bool didError = false; bool didError = false;
Future<void> handleError(dynamic exception, StackTrace? stack) async { Future<void> handleError(Object exception, StackTrace? stack) async {
if (didError) { if (didError) {
return; return;
} }
...@@ -1118,7 +1118,7 @@ class _ErrorImageCompleter extends ImageStreamCompleter { ...@@ -1118,7 +1118,7 @@ class _ErrorImageCompleter extends ImageStreamCompleter {
void setError({ void setError({
DiagnosticsNode? context, DiagnosticsNode? context,
dynamic exception, required Object exception,
StackTrace? stack, StackTrace? stack,
InformationCollector? informationCollector, InformationCollector? informationCollector,
bool silent = false, bool silent = false,
......
...@@ -233,7 +233,7 @@ typedef ImageChunkListener = void Function(ImageChunkEvent event); ...@@ -233,7 +233,7 @@ typedef ImageChunkListener = void Function(ImageChunkEvent event);
/// ///
/// Used in [ImageStreamListener], as well as by [ImageCache.putIfAbsent] and /// Used in [ImageStreamListener], as well as by [ImageCache.putIfAbsent] and
/// [precacheImage], to report errors. /// [precacheImage], to report errors.
typedef ImageErrorListener = void Function(dynamic exception, StackTrace? stackTrace); typedef ImageErrorListener = void Function(Object exception, StackTrace? stackTrace);
/// An immutable notification of image bytes that have been incrementally loaded. /// An immutable notification of image bytes that have been incrementally loaded.
/// ///
...@@ -655,7 +655,7 @@ abstract class ImageStreamCompleter with Diagnosticable { ...@@ -655,7 +655,7 @@ abstract class ImageStreamCompleter with Diagnosticable {
@protected @protected
void reportError({ void reportError({
DiagnosticsNode? context, DiagnosticsNode? context,
dynamic exception, required Object exception,
StackTrace? stack, StackTrace? stack,
InformationCollector? informationCollector, InformationCollector? informationCollector,
bool silent = false, bool silent = false,
...@@ -747,7 +747,7 @@ class OneFrameImageStreamCompleter extends ImageStreamCompleter { ...@@ -747,7 +747,7 @@ class OneFrameImageStreamCompleter extends ImageStreamCompleter {
/// FlutterErrorDetails]). /// FlutterErrorDetails]).
OneFrameImageStreamCompleter(Future<ImageInfo> image, { InformationCollector? informationCollector }) OneFrameImageStreamCompleter(Future<ImageInfo> image, { InformationCollector? informationCollector })
: assert(image != null) { : assert(image != null) {
image.then<void>(setImage, onError: (dynamic error, StackTrace stack) { image.then<void>(setImage, onError: (Object error, StackTrace stack) {
reportError( reportError(
context: ErrorDescription('resolving a single-frame image stream'), context: ErrorDescription('resolving a single-frame image stream'),
exception: error, exception: error,
...@@ -819,7 +819,7 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter { ...@@ -819,7 +819,7 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
_informationCollector = informationCollector, _informationCollector = informationCollector,
_scale = scale { _scale = scale {
this.debugLabel = debugLabel; this.debugLabel = debugLabel;
codec.then<void>(_handleCodecReady, onError: (dynamic error, StackTrace stack) { codec.then<void>(_handleCodecReady, onError: (Object error, StackTrace stack) {
reportError( reportError(
context: ErrorDescription('resolving an image codec'), context: ErrorDescription('resolving an image codec'),
exception: error, exception: error,
...@@ -830,7 +830,7 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter { ...@@ -830,7 +830,7 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
}); });
if (chunkEvents != null) { if (chunkEvents != null) {
chunkEvents.listen(reportImageChunkEvent, chunkEvents.listen(reportImageChunkEvent,
onError: (dynamic error, StackTrace stack) { onError: (Object error, StackTrace stack) {
reportError( reportError(
context: ErrorDescription('loading an image'), context: ErrorDescription('loading an image'),
exception: error, exception: error,
......
...@@ -1307,7 +1307,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im ...@@ -1307,7 +1307,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
/// Used in debug messages. /// Used in debug messages.
Object? debugCreator; Object? debugCreator;
void _debugReportException(String method, dynamic exception, StackTrace stack) { void _debugReportException(String method, Object exception, StackTrace stack) {
FlutterError.reportError(FlutterErrorDetails( FlutterError.reportError(FlutterErrorDetails(
exception: exception, exception: exception,
stack: stack, stack: stack,
......
...@@ -4526,7 +4526,7 @@ class ErrorWidget extends LeafRenderObjectWidget { ...@@ -4526,7 +4526,7 @@ class ErrorWidget extends LeafRenderObjectWidget {
message = _stringify(details.exception) + '\nSee also: https://flutter.dev/docs/testing/errors'; message = _stringify(details.exception) + '\nSee also: https://flutter.dev/docs/testing/errors';
return true; return true;
}()); }());
final dynamic exception = details.exception; final Object exception = details.exception;
return ErrorWidget.withDetails(message: message, error: exception is FlutterError ? exception : null); return ErrorWidget.withDetails(message: message, error: exception is FlutterError ? exception : null);
} }
...@@ -6312,7 +6312,7 @@ class DebugCreator { ...@@ -6312,7 +6312,7 @@ class DebugCreator {
FlutterErrorDetails _debugReportException( FlutterErrorDetails _debugReportException(
DiagnosticsNode context, DiagnosticsNode context,
dynamic exception, Object exception,
StackTrace? stack, { StackTrace? stack, {
InformationCollector? informationCollector, InformationCollector? informationCollector,
}) { }) {
......
...@@ -123,7 +123,7 @@ Future<void> precacheImage( ...@@ -123,7 +123,7 @@ Future<void> precacheImage(
stream.removeListener(listener!); stream.removeListener(listener!);
}); });
}, },
onError: (dynamic exception, StackTrace? stackTrace) { onError: (Object exception, StackTrace? stackTrace) {
if (!completer.isCompleted) { if (!completer.isCompleted) {
completer.complete(); completer.complete();
} }
......
...@@ -393,7 +393,7 @@ class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<Ren ...@@ -393,7 +393,7 @@ class _RenderLayoutBuilder extends RenderBox with RenderObjectWithChildMixin<Ren
FlutterErrorDetails _debugReportException( FlutterErrorDetails _debugReportException(
DiagnosticsNode context, DiagnosticsNode context,
dynamic exception, Object exception,
StackTrace stack, { StackTrace stack, {
InformationCollector? informationCollector, InformationCollector? informationCollector,
}) { }) {
......
...@@ -1670,7 +1670,7 @@ class KeepAlive extends ParentDataWidget<KeepAliveParentDataMixin> { ...@@ -1670,7 +1670,7 @@ class KeepAlive extends ParentDataWidget<KeepAliveParentDataMixin> {
} }
// Return a Widget for the given Exception // Return a Widget for the given Exception
Widget _createErrorWidget(dynamic exception, StackTrace stackTrace) { Widget _createErrorWidget(Object exception, StackTrace stackTrace) {
final FlutterErrorDetails details = FlutterErrorDetails( final FlutterErrorDetails details = FlutterErrorDetails(
exception: exception, exception: exception,
stack: stackTrace, stack: stackTrace,
......
...@@ -57,10 +57,10 @@ void main() { ...@@ -57,10 +57,10 @@ void main() {
'\n' '\n'
'INFO\n' 'INFO\n'
'═════════════════════════════════════════════════════════════════\n', '═════════════════════════════════════════════════════════════════\n',
); );
expect( expect(
FlutterErrorDetails( FlutterErrorDetails(
exception: NullThrownError(),
library: 'LIBRARY', library: 'LIBRARY',
context: ErrorDescription('CONTEXTING'), context: ErrorDescription('CONTEXTING'),
informationCollector: () sync* { informationCollector: () sync* {
...@@ -68,11 +68,10 @@ void main() { ...@@ -68,11 +68,10 @@ void main() {
}, },
).toString(), ).toString(),
'══╡ EXCEPTION CAUGHT BY LIBRARY ╞════════════════════════════════\n' '══╡ EXCEPTION CAUGHT BY LIBRARY ╞════════════════════════════════\n'
'The following Null object was thrown CONTEXTING:\n' 'The null value was thrown CONTEXTING.\n'
' null\n'
'\n' '\n'
'INFO\n' 'INFO\n'
'═════════════════════════════════════════════════════════════════\n', '═════════════════════════════════════════════════════════════════\n'
); );
expect( expect(
FlutterErrorDetails( FlutterErrorDetails(
...@@ -114,11 +113,10 @@ void main() { ...@@ -114,11 +113,10 @@ void main() {
'═════════════════════════════════════════════════════════════════\n', '═════════════════════════════════════════════════════════════════\n',
); );
expect( expect(
const FlutterErrorDetails().toString(), FlutterErrorDetails(exception: NullThrownError()).toString(),
'══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n' '══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞══════════════════════\n'
'The following Null object was thrown:\n' 'The null value was thrown.\n'
' null\n' '═════════════════════════════════════════════════════════════════\n'
'═════════════════════════════════════════════════════════════════\n',
); );
}); });
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import '../flutter_test_alternative.dart'; import '../flutter_test_alternative.dart';
dynamic getAssertionErrorWithMessage() { Object getAssertionErrorWithMessage() {
try { try {
assert(false, 'Message goes here.'); assert(false, 'Message goes here.');
} catch (e) { } catch (e) {
...@@ -16,7 +16,7 @@ dynamic getAssertionErrorWithMessage() { ...@@ -16,7 +16,7 @@ dynamic getAssertionErrorWithMessage() {
throw 'assert failed'; throw 'assert failed';
} }
dynamic getAssertionErrorWithoutMessage() { Object getAssertionErrorWithoutMessage() {
try { try {
assert(false); assert(false);
} catch (e) { } catch (e) {
...@@ -25,7 +25,7 @@ dynamic getAssertionErrorWithoutMessage() { ...@@ -25,7 +25,7 @@ dynamic getAssertionErrorWithoutMessage() {
throw 'assert failed'; throw 'assert failed';
} }
dynamic getAssertionErrorWithLongMessage() { Object getAssertionErrorWithLongMessage() {
try { try {
assert(false, 'word ' * 100); assert(false, 'word ' * 100);
} catch (e) { } catch (e) {
......
...@@ -117,7 +117,7 @@ void main() { ...@@ -117,7 +117,7 @@ void main() {
}); });
expect(errors, hasLength(2)); expect(errors, hasLength(2));
expect(errors.first.exception, isFlutterError); expect(errors.first.exception, isFlutterError);
expect(errors.first.exception.toStringDeep(), expect((errors.first.exception as FlutterError).toStringDeep(),
'FlutterError\n' 'FlutterError\n'
' RenderAspectRatio has unbounded constraints.\n' ' RenderAspectRatio has unbounded constraints.\n'
' This RenderAspectRatio was given an aspect ratio of 0.5 but was\n' ' This RenderAspectRatio was given an aspect ratio of 0.5 but was\n'
......
...@@ -27,7 +27,7 @@ class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, Ser ...@@ -27,7 +27,7 @@ class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, Ser
TestRenderingFlutterBinding({ this.onErrors }) { TestRenderingFlutterBinding({ this.onErrors }) {
FlutterError.onError = (FlutterErrorDetails details) { FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.dumpErrorToConsole(details); FlutterError.dumpErrorToConsole(details);
Zone.current.parent!.handleUncaughtError(details.exception as Object, details.stack!); Zone.current.parent!.handleUncaughtError(details.exception, details.stack!);
}; };
} }
......
...@@ -1627,7 +1627,7 @@ void main() { ...@@ -1627,7 +1627,7 @@ void main() {
} }
expect(errors, isNotEmpty); expect(errors, isNotEmpty);
expect(errors.first.exception, isFlutterError); expect(errors.first.exception, isFlutterError);
expect(errors.first.exception.toStringDeep(), message); expect((errors.first.exception as FlutterError).toStringDeep(), message);
} }
testWidgets('Horizontal viewport was given unbounded height', (WidgetTester tester) async { testWidgets('Horizontal viewport was given unbounded height', (WidgetTester tester) async {
......
...@@ -301,7 +301,7 @@ void main() { ...@@ -301,7 +301,7 @@ void main() {
expect(errors.length, isNonZero); expect(errors.length, isNonZero);
expect(errors.first, isNotNull); expect(errors.first, isNotNull);
expect(errors.first.exception, isFlutterError); expect(errors.first.exception, isFlutterError);
expect(errors.first.exception.toStringDeep(), equalsIgnoringHashCodes(message)); expect((errors.first.exception as FlutterError).toStringDeep(), equalsIgnoringHashCodes(message));
} }
testWidgets('layoutChild on non existent child', (WidgetTester tester) async { testWidgets('layoutChild on non existent child', (WidgetTester tester) async {
......
...@@ -134,7 +134,7 @@ void main() { ...@@ -134,7 +134,7 @@ void main() {
} }
expect(errors, isNotEmpty); expect(errors, isNotEmpty);
expect(errors.first.exception, isFlutterError); expect(errors.first.exception, isFlutterError);
expect(errors.first.exception.toStringDeep(), equalsIgnoringHashCodes( expect((errors.first.exception as FlutterError).toStringDeep(), equalsIgnoringHashCodes(
'FlutterError\n' 'FlutterError\n'
' RenderListBody must have unlimited space along its main axis.\n' ' RenderListBody must have unlimited space along its main axis.\n'
' RenderListBody does not clip or resize its children, so it must\n' ' RenderListBody does not clip or resize its children, so it must\n'
...@@ -183,7 +183,7 @@ void main() { ...@@ -183,7 +183,7 @@ void main() {
} }
expect(errors, isNotEmpty); expect(errors, isNotEmpty);
expect(errors.first.exception, isFlutterError); expect(errors.first.exception, isFlutterError);
expect(errors.first.exception.toStringDeep(), equalsIgnoringHashCodes( expect((errors.first.exception as FlutterError).toStringDeep(), equalsIgnoringHashCodes(
'FlutterError\n' 'FlutterError\n'
' RenderListBody must have a bounded constraint for its cross axis.\n' ' RenderListBody must have a bounded constraint for its cross axis.\n'
' RenderListBody forces its children to expand to fit the\n' ' RenderListBody forces its children to expand to fit the\n'
......
...@@ -686,7 +686,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase ...@@ -686,7 +686,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
}; };
final Completer<void> testCompleter = Completer<void>(); final Completer<void> testCompleter = Completer<void>();
final VoidCallback testCompletionHandler = _createTestCompletionHandler(description, testCompleter); final VoidCallback testCompletionHandler = _createTestCompletionHandler(description, testCompleter);
void handleUncaughtError(dynamic exception, StackTrace stack) { void handleUncaughtError(Object exception, StackTrace stack) {
if (testCompleter.isCompleted) { if (testCompleter.isCompleted) {
// Well this is not a good sign. // Well this is not a good sign.
// Ideally, once the test has failed we would stop getting errors from the test. // Ideally, once the test has failed we would stop getting errors from the test.
...@@ -765,7 +765,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase ...@@ -765,7 +765,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
_parentZone!.run<void>(testCompletionHandler); _parentZone!.run<void>(testCompletionHandler);
} }
final ZoneSpecification errorHandlingZoneSpecification = ZoneSpecification( final ZoneSpecification errorHandlingZoneSpecification = ZoneSpecification(
handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone, dynamic exception, StackTrace stack) { handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone, Object exception, StackTrace stack) {
handleUncaughtError(exception, stack); handleUncaughtError(exception, stack);
} }
); );
...@@ -1013,7 +1013,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding { ...@@ -1013,7 +1013,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
return realAsyncZone.run<Future<T>>(() { return realAsyncZone.run<Future<T>>(() {
_pendingAsyncTasks = Completer<void>(); _pendingAsyncTasks = Completer<void>();
return callback().catchError((dynamic exception, StackTrace stack) { return callback().catchError((Object exception, StackTrace stack) {
FlutterError.reportError(FlutterErrorDetails( FlutterError.reportError(FlutterErrorDetails(
exception: exception, exception: exception,
stack: stack, stack: stack,
......
...@@ -28,7 +28,7 @@ Future<void> main() async { ...@@ -28,7 +28,7 @@ Future<void> main() async {
completer.future.then( completer.future.then(
(String value) {}, (String value) {},
onError: (dynamic error, StackTrace stack) { onError: (Object error, StackTrace stack) {
assert(stack is stack_trace.Chain); assert(stack is stack_trace.Chain);
FlutterError.reportError(FlutterErrorDetails( FlutterError.reportError(FlutterErrorDetails(
exception: error, exception: error,
......
...@@ -10,7 +10,7 @@ import 'package:flutter_test/flutter_test.dart'; ...@@ -10,7 +10,7 @@ import 'package:flutter_test/flutter_test.dart';
Future<void> main(FutureOr<void> testMain()) async { Future<void> main(FutureOr<void> testMain()) async {
reportTestException = (FlutterErrorDetails details, String testDescription) { reportTestException = (FlutterErrorDetails details, String testDescription) {
expect(details.exception, isA<StateError>()); expect(details.exception, isA<StateError>());
expect(details.exception.message, 'foo'); expect((details.exception as StateError).message, 'foo');
expect(testDescription, 'custom exception reporter'); expect(testDescription, 'custom exception reporter');
}; };
......
...@@ -737,7 +737,7 @@ void main() { ...@@ -737,7 +737,7 @@ void main() {
}, () {}); }, () {});
expect(flutterErrorDetails.exception, isA<AssertionError>()); expect(flutterErrorDetails.exception, isA<AssertionError>());
expect(flutterErrorDetails.exception!.message, 'A Timer is still pending even after the widget tree was disposed.'); expect((flutterErrorDetails.exception as AssertionError).message, 'A Timer is still pending even after the widget tree was disposed.');
}); });
}); });
} }
......
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