From 23f3f709d09f43ebd46340842f334e995a946137 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 27 Mar 2026 17:09:55 -0700 Subject: [PATCH 1/6] Create error_reporting_test.dart --- .../test/error_reporting_test.dart | 296 ++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 packages/ui_primitives/test/error_reporting_test.dart diff --git a/packages/ui_primitives/test/error_reporting_test.dart b/packages/ui_primitives/test/error_reporting_test.dart new file mode 100644 index 000000000..7fb5365d2 --- /dev/null +++ b/packages/ui_primitives/test/error_reporting_test.dart @@ -0,0 +1,296 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +library; + +import 'package:test/test.dart'; +import 'package:ui_primitives/ui_primitives.dart'; + +Object getAssertionErrorWithMessage() { + try { + assert(false, 'Message goes here.'); + } catch (e) { + return e; + } + throw 'assert failed'; +} + +Object getAssertionErrorWithoutMessage() { + try { + assert(false); + } catch (e) { + return e; + } + throw 'assert failed'; +} + +Object getAssertionErrorWithLongMessage() { + try { + assert(false, 'word ' * 100); + } catch (e) { + return e; + } + throw 'assert failed'; +} + +Future getSampleStack() async { + return Future.sync(() => StackTrace.current); +} + +Future main() async { + final console = []; + + final StackTrace sampleStack = await getSampleStack(); + + setUp(() async { + expect(debugPrint, equals(debugPrintThrottled)); + debugPrint = (String? message, {int? wrapWidth}) { + console.add(message); + }; + }); + + tearDown(() async { + expect(console, isEmpty); + debugPrint = debugPrintThrottled; + }); + + test('Error reporting - assert with message', () async { + expect(console, isEmpty); + UiError.dumpErrorToConsole( + UiErrorDetails( + exception: getAssertionErrorWithMessage(), + stack: sampleStack, + library: 'error handling test', + context: ErrorDescription('testing the error handling logic'), + informationCollector: () sync* { + yield ErrorDescription('line 1 of extra information'); + yield ErrorHint('line 2 of extra information\n'); + }, + ), + ); + expect( + console.join('\n'), + matches( + r'^══╡ EXCEPTION CAUGHT BY ERROR HANDLING TEST ╞═══════════════════════════════════════════════════════\n' + r'The following assertion was thrown testing the error handling logic:\n' + r'Message goes here\.\n' + r"'[^']+flutter/test/foundation/error_reporting_test\.dart':\n" + r"Failed assertion: line [0-9]+ pos [0-9]+: 'false'\n" + r'\n' + r'When the exception was thrown, this was the stack:\n' + r'#0 getSampleStack\. \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' + r'#2 getSampleStack \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' + r'#3 main \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' + r'(.+\n)+', // TODO(ianh): when fixing #4021, also filter out frames from the test infrastructure below the first call to our main() + ), + ); + console.clear(); + UiError.dumpErrorToConsole( + UiErrorDetails(exception: getAssertionErrorWithMessage()), + ); + expect( + console.join('\n'), + 'Another exception was thrown: Message goes here.', + ); + console.clear(); + UiError.resetErrorCount(); + }); + + test('Error reporting - assert with long message', () async { + expect(console, isEmpty); + UiError.dumpErrorToConsole( + UiErrorDetails(exception: getAssertionErrorWithLongMessage()), + ); + expect( + console.join('\n'), + matches( + r'^══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════\n' + r'The following assertion was thrown:\n' + r'word word word word word word word word word word word word word word word word word word word word\n' + r'word word word word word word word word word word word word word word word word word word word word\n' + r'word word word word word word word word word word word word word word word word word word word word\n' + r'word word word word word word word word word word word word word word word word word word word word\n' + r'word word word word word word word word word word word word word word word word word word word word\n' + r"'[^']+flutter/test/foundation/error_reporting_test\.dart':\n" + r"Failed assertion: line [0-9]+ pos [0-9]+: 'false'\n" + r'════════════════════════════════════════════════════════════════════════════════════════════════════$', + ), + ); + console.clear(); + UiError.dumpErrorToConsole( + UiErrorDetails(exception: getAssertionErrorWithLongMessage()), + ); + expect( + console.join('\n'), + 'Another exception was thrown: ' + 'word word word word word word word word word word word word word word word word word word word word ' + 'word word word word word word word word word word word word word word word word word word word word ' + 'word word word word word word word word word word word word word word word word word word word word ' + 'word word word word word word word word word word word word word word word word word word word word ' + 'word word word word word word word word word word word word word word word word word word word word', + ); + console.clear(); + UiError.resetErrorCount(); + }); + + test('Error reporting - assert with no message', () async { + expect(console, isEmpty); + UiError.dumpErrorToConsole( + UiErrorDetails( + exception: getAssertionErrorWithoutMessage(), + stack: sampleStack, + library: 'error handling test', + context: ErrorDescription('testing the error handling logic'), + informationCollector: () sync* { + yield ErrorDescription('line 1 of extra information'); + yield ErrorDescription( + 'line 2 of extra information\n', + ); // the trailing newlines here are intentional + }, + ), + ); + expect( + console.join('\n'), + matches( + r'^══╡ EXCEPTION CAUGHT BY ERROR HANDLING TEST ╞═══════════════════════════════════════════════════════\n' + r'The following assertion was thrown testing the error handling logic:\n' + r"'[^']+flutter/test/foundation/error_reporting_test\.dart':[\n ]" + r"Failed[\n ]assertion:[\n ]line[\n ][0-9]+[\n ]pos[\n ][0-9]+:[\n ]'false':[\n ]is[\n ]not[\n ]true\.\n" + r'\n' + r'When the exception was thrown, this was the stack:\n' + r'#0 getSampleStack\. \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' + r'#2 getSampleStack \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' + r'#3 main \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' + r'(.+\n)+', // TODO(ianh): when fixing #4021, also filter out frames from the test infrastructure below the first call to our main() + ), + ); + console.clear(); + UiError.dumpErrorToConsole( + UiErrorDetails(exception: getAssertionErrorWithoutMessage()), + ); + expect( + console.join('\n'), + matches( + r"Another exception was thrown: '[^']+flutter/test/foundation/error_reporting_test\.dart': Failed assertion: line [0-9]+ pos [0-9]+: 'false': is not true\.", + ), + ); + console.clear(); + UiError.resetErrorCount(); + }); + + test('Error reporting - NoSuchMethodError', () async { + expect(console, isEmpty); + final Object exception = NoSuchMethodError.withInvocation( + 5, + Invocation.method(#foo, [2, 4]), + ); + + UiError.dumpErrorToConsole(UiErrorDetails(exception: exception)); + expect( + console.join('\n'), + matches( + r'^══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════\n' + r'The following NoSuchMethodError was thrown:\n' + r'int has no foo method accepting arguments \(_, _\)\n' + r'════════════════════════════════════════════════════════════════════════════════════════════════════$', + ), + ); + console.clear(); + UiError.dumpErrorToConsole(UiErrorDetails(exception: exception)); + expect( + console.join('\n'), + 'Another exception was thrown: NoSuchMethodError: int has no foo method accepting arguments (_, _)', + ); + console.clear(); + UiError.resetErrorCount(); + }); + + test('Error reporting - NoSuchMethodError', () async { + expect(console, isEmpty); + UiError.dumpErrorToConsole(const UiErrorDetails(exception: 'hello')); + expect( + console.join('\n'), + matches( + r'^══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════\n' + r'The following message was thrown:\n' + r'hello\n' + r'════════════════════════════════════════════════════════════════════════════════════════════════════$', + ), + ); + console.clear(); + UiError.dumpErrorToConsole(const UiErrorDetails(exception: 'hello again')); + expect(console.join('\n'), 'Another exception was thrown: hello again'); + console.clear(); + UiError.resetErrorCount(); + }); + + // Regression test for https://github.com/flutter/flutter/issues/62223 + test('Error reporting - empty stack', () async { + expect(console, isEmpty); + UiError.dumpErrorToConsole( + UiErrorDetails( + exception: 'exception - empty stack', + stack: StackTrace.fromString(''), + ), + ); + expect( + console.join('\n'), + matches( + r'^══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════\n' + r'The following message was thrown:\n' + r'exception - empty stack\n' + r'\n' + r'When the exception was thrown, this was the stack\n' + r'════════════════════════════════════════════════════════════════════════════════════════════════════$', + ), + ); + console.clear(); + UiError.resetErrorCount(); + }); + + test('Stack traces are not truncated', () async { + const stackString = ''' +#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:42:39) +#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:38:5) +#2 new Text (package:flutter/src/widgets/text.dart:287:10) +#3 _MyHomePageState.build (package:hello_flutter/main.dart:72:16) +#4 StatefulElement.build (package:flutter/src/widgets/framework.dart:4414:27) +#5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4303:15) +#6 Element.rebuild (package:flutter/src/widgets/framework.dart:4027:5) +#7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4286:5) +#8 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4461:11) +#9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4281:5) +#10 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3276:14)'''; + + expect(console, isEmpty); + UiError.dumpErrorToConsole( + UiErrorDetails( + exception: AssertionError('Test assertion'), + stack: StackTrace.fromString(stackString), + ), + ); + final String x = console.join('\n'); + expect( + x, + startsWith( + ''' +══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════ +The following assertion was thrown: +Assertion failed: "Test assertion" + +When the exception was thrown, this was the stack: +#2 new Text (package:flutter/src/widgets/text.dart:287:10) +#3 _MyHomePageState.build (package:hello_flutter/main.dart:72:16) +#4 StatefulElement.build (package:flutter/src/widgets/framework.dart:4414:27) +#5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4303:15) +#6 Element.rebuild (package:flutter/src/widgets/framework.dart:4027:5) +#7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4286:5) +#8 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4461:11) +#9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4281:5)''', + ), + ); + console.clear(); + UiError.resetErrorCount(); + }); +} From 0a9245f1660b9eaecd66508d1ceed1e46c0b545f Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 27 Mar 2026 17:26:04 -0700 Subject: [PATCH 2/6] - --- packages/ui_primitives/pubspec.yaml | 2 +- .../test/error_reporting_test.dart | 79 +++++++++++-------- 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/packages/ui_primitives/pubspec.yaml b/packages/ui_primitives/pubspec.yaml index 79ac07e33..d52ed42c5 100644 --- a/packages/ui_primitives/pubspec.yaml +++ b/packages/ui_primitives/pubspec.yaml @@ -5,7 +5,7 @@ name: ui_primitives description: Highly experimental package. repository: https://github.com/flutter/genui/tree/main/packages/ui_primitives -version: 0.0.1-dev-005 +version: 0.0.1-dev-006 resolution: workspace diff --git a/packages/ui_primitives/test/error_reporting_test.dart b/packages/ui_primitives/test/error_reporting_test.dart index 7fb5365d2..9bdb31e21 100644 --- a/packages/ui_primitives/test/error_reporting_test.dart +++ b/packages/ui_primitives/test/error_reporting_test.dart @@ -38,6 +38,13 @@ Future getSampleStack() async { return Future.sync(() => StackTrace.current); } +String _setPath(String source) { + return source.replaceAll( + r'$path$', + 'ui_primitives/test/error_reporting_test.dart', + ); +} + Future main() async { final console = []; @@ -72,17 +79,19 @@ Future main() async { expect( console.join('\n'), matches( - r'^══╡ EXCEPTION CAUGHT BY ERROR HANDLING TEST ╞═══════════════════════════════════════════════════════\n' - r'The following assertion was thrown testing the error handling logic:\n' - r'Message goes here\.\n' - r"'[^']+flutter/test/foundation/error_reporting_test\.dart':\n" - r"Failed assertion: line [0-9]+ pos [0-9]+: 'false'\n" - r'\n' - r'When the exception was thrown, this was the stack:\n' - r'#0 getSampleStack\. \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' - r'#2 getSampleStack \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' - r'#3 main \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' - r'(.+\n)+', // TODO(ianh): when fixing #4021, also filter out frames from the test infrastructure below the first call to our main() + _setPath( + r'^══╡ EXCEPTION CAUGHT BY ERROR HANDLING TEST ╞═══════════════════════════════════════════════════════\n' + r'The following assertion was thrown testing the error handling logic:\n' + r'Message goes here\.\n' + r"'[^']+$path$':\n" + r"Failed assertion: line [0-9]+ pos [0-9]+: 'false'\n" + r'\n' + r'When the exception was thrown, this was the stack:\n' + r'#0 getSampleStack\. \([^)]+$path$:[0-9]+:[0-9]+\)\n' + r'#2 getSampleStack \([^)]+$path$:[0-9]+:[0-9]+\)\n' + r'#3 main \([^)]+$path$:[0-9]+:[0-9]+\)\n' + r'(.+\n)+', // TODO(ianh): when fixing #4021, also filter out frames from the test infrastructure below the first call to our main() + ), ), ); console.clear(); @@ -105,16 +114,18 @@ Future main() async { expect( console.join('\n'), matches( - r'^══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════\n' - r'The following assertion was thrown:\n' - r'word word word word word word word word word word word word word word word word word word word word\n' - r'word word word word word word word word word word word word word word word word word word word word\n' - r'word word word word word word word word word word word word word word word word word word word word\n' - r'word word word word word word word word word word word word word word word word word word word word\n' - r'word word word word word word word word word word word word word word word word word word word word\n' - r"'[^']+flutter/test/foundation/error_reporting_test\.dart':\n" - r"Failed assertion: line [0-9]+ pos [0-9]+: 'false'\n" - r'════════════════════════════════════════════════════════════════════════════════════════════════════$', + _setPath( + r'^══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════\n' + r'The following assertion was thrown:\n' + r'word word word word word word word word word word word word word word word word word word word word\n' + r'word word word word word word word word word word word word word word word word word word word word\n' + r'word word word word word word word word word word word word word word word word word word word word\n' + r'word word word word word word word word word word word word word word word word word word word word\n' + r'word word word word word word word word word word word word word word word word word word word word\n' + r"'[^']+$path$':\n" + r"Failed assertion: line [0-9]+ pos [0-9]+: 'false'\n" + r'════════════════════════════════════════════════════════════════════════════════════════════════════$', + ), ), ); console.clear(); @@ -153,16 +164,18 @@ Future main() async { expect( console.join('\n'), matches( - r'^══╡ EXCEPTION CAUGHT BY ERROR HANDLING TEST ╞═══════════════════════════════════════════════════════\n' - r'The following assertion was thrown testing the error handling logic:\n' - r"'[^']+flutter/test/foundation/error_reporting_test\.dart':[\n ]" - r"Failed[\n ]assertion:[\n ]line[\n ][0-9]+[\n ]pos[\n ][0-9]+:[\n ]'false':[\n ]is[\n ]not[\n ]true\.\n" - r'\n' - r'When the exception was thrown, this was the stack:\n' - r'#0 getSampleStack\. \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' - r'#2 getSampleStack \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' - r'#3 main \([^)]+flutter/test/foundation/error_reporting_test\.dart:[0-9]+:[0-9]+\)\n' - r'(.+\n)+', // TODO(ianh): when fixing #4021, also filter out frames from the test infrastructure below the first call to our main() + _setPath( + r'^══╡ EXCEPTION CAUGHT BY ERROR HANDLING TEST ╞═══════════════════════════════════════════════════════\n' + r'The following assertion was thrown testing the error handling logic:\n' + r"'[^']+$path$':[\n ]" + r"Failed[\n ]assertion:[\n ]line[\n ][0-9]+[\n ]pos[\n ][0-9]+:[\n ]'false':[\n ]is[\n ]not[\n ]true\.\n" + r'\n' + r'When the exception was thrown, this was the stack:\n' + r'#0 getSampleStack\. \([^)]+$path$:[0-9]+:[0-9]+\)\n' + r'#2 getSampleStack \([^)]+$path$:[0-9]+:[0-9]+\)\n' + r'#3 main \([^)]+$path$:[0-9]+:[0-9]+\)\n' + r'(.+\n)+', // TODO(ianh): when fixing #4021, also filter out frames from the test infrastructure below the first call to our main() + ), ), ); console.clear(); @@ -172,7 +185,9 @@ Future main() async { expect( console.join('\n'), matches( - r"Another exception was thrown: '[^']+flutter/test/foundation/error_reporting_test\.dart': Failed assertion: line [0-9]+ pos [0-9]+: 'false': is not true\.", + _setPath( + r"Another exception was thrown: '[^']+$path$': Failed assertion: line [0-9]+ pos [0-9]+: 'false': is not true\.", + ), ), ); console.clear(); From a3db6afb3e43943311862e8a262c208f9c9314f2 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 27 Mar 2026 17:27:54 -0700 Subject: [PATCH 3/6] Update error_reporting_test.dart --- packages/ui_primitives/test/error_reporting_test.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/ui_primitives/test/error_reporting_test.dart b/packages/ui_primitives/test/error_reporting_test.dart index 9bdb31e21..9c92be624 100644 --- a/packages/ui_primitives/test/error_reporting_test.dart +++ b/packages/ui_primitives/test/error_reporting_test.dart @@ -22,6 +22,7 @@ Object getAssertionErrorWithoutMessage() { } catch (e) { return e; } + // ignore: only_throw_errors throw 'assert failed'; } @@ -31,6 +32,7 @@ Object getAssertionErrorWithLongMessage() { } catch (e) { return e; } + // ignore: only_throw_errors throw 'assert failed'; } From b34cc913e880d149810be2db20493a6a04f23cf4 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 27 Mar 2026 17:28:48 -0700 Subject: [PATCH 4/6] Update error_reporting_test.dart --- packages/ui_primitives/test/error_reporting_test.dart | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/ui_primitives/test/error_reporting_test.dart b/packages/ui_primitives/test/error_reporting_test.dart index 9c92be624..112d403bd 100644 --- a/packages/ui_primitives/test/error_reporting_test.dart +++ b/packages/ui_primitives/test/error_reporting_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -library; - import 'package:test/test.dart'; import 'package:ui_primitives/ui_primitives.dart'; @@ -13,7 +11,7 @@ Object getAssertionErrorWithMessage() { } catch (e) { return e; } - throw 'assert failed'; + throw Error(); } Object getAssertionErrorWithoutMessage() { @@ -22,8 +20,7 @@ Object getAssertionErrorWithoutMessage() { } catch (e) { return e; } - // ignore: only_throw_errors - throw 'assert failed'; + throw Error(); } Object getAssertionErrorWithLongMessage() { From 8b8eaf73bf9b61a715cd188b6b3b3bf4aa115c61 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 27 Mar 2026 17:32:34 -0700 Subject: [PATCH 5/6] Update error_reporting_test.dart --- .../test/error_reporting_test.dart | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/ui_primitives/test/error_reporting_test.dart b/packages/ui_primitives/test/error_reporting_test.dart index 112d403bd..5d042b88a 100644 --- a/packages/ui_primitives/test/error_reporting_test.dart +++ b/packages/ui_primitives/test/error_reporting_test.dart @@ -39,7 +39,7 @@ Future getSampleStack() async { String _setPath(String source) { return source.replaceAll( - r'$path$', + r'$thisTestPath', 'ui_primitives/test/error_reporting_test.dart', ); } @@ -82,13 +82,13 @@ Future main() async { r'^══╡ EXCEPTION CAUGHT BY ERROR HANDLING TEST ╞═══════════════════════════════════════════════════════\n' r'The following assertion was thrown testing the error handling logic:\n' r'Message goes here\.\n' - r"'[^']+$path$':\n" + r"'[^']+$thisTestPath':\n" r"Failed assertion: line [0-9]+ pos [0-9]+: 'false'\n" r'\n' r'When the exception was thrown, this was the stack:\n' - r'#0 getSampleStack\. \([^)]+$path$:[0-9]+:[0-9]+\)\n' - r'#2 getSampleStack \([^)]+$path$:[0-9]+:[0-9]+\)\n' - r'#3 main \([^)]+$path$:[0-9]+:[0-9]+\)\n' + r'#0 getSampleStack\. \([^)]+$thisTestPath:[0-9]+:[0-9]+\)\n' + r'#2 getSampleStack \([^)]+$thisTestPath:[0-9]+:[0-9]+\)\n' + r'#3 main \([^)]+$thisTestPath:[0-9]+:[0-9]+\)\n' r'(.+\n)+', // TODO(ianh): when fixing #4021, also filter out frames from the test infrastructure below the first call to our main() ), ), @@ -121,7 +121,7 @@ Future main() async { r'word word word word word word word word word word word word word word word word word word word word\n' r'word word word word word word word word word word word word word word word word word word word word\n' r'word word word word word word word word word word word word word word word word word word word word\n' - r"'[^']+$path$':\n" + r"'[^']+$thisTestPath':\n" r"Failed assertion: line [0-9]+ pos [0-9]+: 'false'\n" r'════════════════════════════════════════════════════════════════════════════════════════════════════$', ), @@ -166,13 +166,13 @@ Future main() async { _setPath( r'^══╡ EXCEPTION CAUGHT BY ERROR HANDLING TEST ╞═══════════════════════════════════════════════════════\n' r'The following assertion was thrown testing the error handling logic:\n' - r"'[^']+$path$':[\n ]" + r"'[^']+$thisTestPath':[\n ]" r"Failed[\n ]assertion:[\n ]line[\n ][0-9]+[\n ]pos[\n ][0-9]+:[\n ]'false':[\n ]is[\n ]not[\n ]true\.\n" r'\n' r'When the exception was thrown, this was the stack:\n' - r'#0 getSampleStack\. \([^)]+$path$:[0-9]+:[0-9]+\)\n' - r'#2 getSampleStack \([^)]+$path$:[0-9]+:[0-9]+\)\n' - r'#3 main \([^)]+$path$:[0-9]+:[0-9]+\)\n' + r'#0 getSampleStack\. \([^)]+$thisTestPath:[0-9]+:[0-9]+\)\n' + r'#2 getSampleStack \([^)]+$thisTestPath:[0-9]+:[0-9]+\)\n' + r'#3 main \([^)]+$thisTestPath:[0-9]+:[0-9]+\)\n' r'(.+\n)+', // TODO(ianh): when fixing #4021, also filter out frames from the test infrastructure below the first call to our main() ), ), @@ -185,7 +185,7 @@ Future main() async { console.join('\n'), matches( _setPath( - r"Another exception was thrown: '[^']+$path$': Failed assertion: line [0-9]+ pos [0-9]+: 'false': is not true\.", + r"Another exception was thrown: '[^']+$thisTestPath': Failed assertion: line [0-9]+ pos [0-9]+: 'false': is not true\.", ), ), ); From 2d0ffb62fef2b0684f6e4abcfe519d5e1d2c673c Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 27 Mar 2026 17:35:30 -0700 Subject: [PATCH 6/6] - --- .../lib/src/foundation/_platform_io.dart | 2 +- .../lib/src/foundation/assertions.dart | 124 +++++++++--------- .../lib/src/foundation/debug.dart | 2 +- .../lib/src/foundation/diagnostics.dart | 4 +- .../lib/src/foundation/platform.dart | 2 +- .../lib/src/foundation/value_notifier.dart | 10 +- packages/ui_primitives/lib/ui_primitives.dart | 4 +- .../test/error_reporting_test.dart | 62 +++++---- 8 files changed, 108 insertions(+), 102 deletions(-) diff --git a/packages/ui_primitives/lib/src/foundation/_platform_io.dart b/packages/ui_primitives/lib/src/foundation/_platform_io.dart index 985832770..506320c43 100644 --- a/packages/ui_primitives/lib/src/foundation/_platform_io.dart +++ b/packages/ui_primitives/lib/src/foundation/_platform_io.dart @@ -37,7 +37,7 @@ platform.TargetPlatform get defaultTargetPlatform { result = platform.debugDefaultTargetPlatformOverride; } if (result == null) { - throw UiError( + throw FrameworkError( 'Unknown platform.\n' '${Platform.operatingSystem} was not recognized as a target platform. ' 'Consider updating the list of TargetPlatforms to include this platform.', diff --git a/packages/ui_primitives/lib/src/foundation/assertions.dart b/packages/ui_primitives/lib/src/foundation/assertions.dart index b59c7e7b0..a56031078 100644 --- a/packages/ui_primitives/lib/src/foundation/assertions.dart +++ b/packages/ui_primitives/lib/src/foundation/assertions.dart @@ -31,14 +31,14 @@ export 'stack_frame.dart' show StackFrame; // class Trace implements StackTrace { late StackTrace vmTrace; } // class Chain implements StackTrace { Trace toTrace() => Trace(); } -/// Signature for [UiError.onError] handler. -typedef FlutterExceptionHandler = void Function(UiErrorDetails details); +/// Signature for [FrameworkError.onError] handler. +typedef FlutterExceptionHandler = void Function(FrameworkErrorDetails details); /// Signature for [DiagnosticPropertiesBuilder] transformer. typedef DiagnosticPropertiesTransformer = Iterable Function(Iterable properties); -/// Signature for [UiErrorDetails.informationCollector] callback +/// Signature for [FrameworkErrorDetails.informationCollector] callback /// and other callbacks that collect information describing an error. typedef InformationCollector = Iterable Function(); @@ -47,7 +47,7 @@ typedef InformationCollector = Iterable Function(); /// /// See also: /// -/// * [UiError.demangleStackTrace], which shows an example +/// * [FrameworkError.demangleStackTrace], which shows an example /// implementation. typedef StackTraceDemangler = StackTrace Function(StackTrace details); @@ -108,7 +108,7 @@ class PartialStackFrame { } /// A class that filters stack frames for additional filtering on -/// [UiError.defaultStackFilter]. +/// [FrameworkError.defaultStackFilter]. abstract class StackFilter { /// This constructor enables subclasses to provide const constructors so that /// they can be used in const expressions. @@ -126,8 +126,8 @@ abstract class StackFilter { /// /// See also: /// -/// * [UiError.addDefaultStackFilter], a method to register additional -/// stack filters for [UiError.defaultStackFilter]. +/// * [FrameworkError.addDefaultStackFilter], a method to register additional +/// stack filters for [FrameworkError.defaultStackFilter]. /// * [StackFrame], a class that can help with parsing stack frames. /// * [PartialStackFrame], a class that helps match partial method information /// to a stack frame. @@ -147,7 +147,7 @@ class RepetitiveStackFrameFilter extends StackFilter { /// The string to replace the frames with. /// /// If the same replacement string is used multiple times in a row, the - /// [UiError.defaultStackFilter] will insert a repeat count after this + /// [FrameworkError.defaultStackFilter] will insert a repeat count after this /// line rather than repeating it. final String replacement; @@ -264,7 +264,7 @@ abstract class _ErrorDiagnostic extends DiagnosticsProperty> { /// * [ErrorHint], which provides specific, non-obvious advice that may be /// applicable. /// * [ErrorSpacer], which renders as a blank line. -/// * [UiError], which is the most common place to use an +/// * [FrameworkError], which is the most common place to use an /// [ErrorDescription]. class ErrorDescription extends _ErrorDiagnostic { /// A lint enforces that this constructor can only be called with a string @@ -291,7 +291,7 @@ class ErrorDescription extends _ErrorDiagnostic { /// so that they can be recognized as related. For example, they shouldn't /// include hash codes. /// -/// A [UiError] must start with an [ErrorSummary] and may not contain +/// A [FrameworkError] must start with an [ErrorSummary] and may not contain /// multiple summaries. /// /// In debug builds, values interpolated into the `message` are @@ -305,7 +305,7 @@ class ErrorDescription extends _ErrorDiagnostic { /// information, etc. /// * [ErrorHint], which provides specific, non-obvious advice that may be /// applicable. -/// * [UiError], which is the most common place to use an [ErrorSummary]. +/// * [FrameworkError], which is the most common place to use an [ErrorSummary]. class ErrorSummary extends _ErrorDiagnostic { /// A lint enforces that this constructor can only be called with a string /// literal to match the limitations of the Dart Kernel transformer that @@ -342,7 +342,7 @@ class ErrorSummary extends _ErrorDiagnostic { /// cause, any information that may help track down the problem, background /// information, etc. /// * [ErrorSpacer], which renders as a blank line. -/// * [UiError], which is the most common place to use an [ErrorHint]. +/// * [FrameworkError], which is the most common place to use an [ErrorHint]. class ErrorHint extends _ErrorDiagnostic { /// A lint enforces that this constructor can only be called with a string /// literal to match the limitations of the Dart Kernel transformer that @@ -366,15 +366,15 @@ class ErrorHint extends _ErrorDiagnostic { /// tune the spacing between other [DiagnosticsNode] objects. class ErrorSpacer extends DiagnosticsProperty { /// Creates an empty space to insert into a list of [DiagnosticsNode] objects - /// typically within a [UiError] object. + /// typically within a [FrameworkError] object. ErrorSpacer() : super('', null, description: '', showName: false); } /// Class for information provided to [FlutterExceptionHandler] callbacks. /// /// {@tool snippet} -/// This is an example of using [UiErrorDetails] when calling -/// [UiError.reportError]. +/// This is an example of using [FrameworkErrorDetails] when calling +/// [FrameworkError.reportError]. /// /// ```dart /// void main() { @@ -394,15 +394,15 @@ class ErrorSpacer extends DiagnosticsProperty { /// /// See also: /// -/// * [UiError.onError], which is called whenever the Flutter framework +/// * [FrameworkError.onError], which is called whenever the Flutter framework /// catches an error. -class UiErrorDetails with Diagnosticable { - /// Creates a [UiErrorDetails] object with the given arguments setting +class FrameworkErrorDetails with Diagnosticable { + /// Creates a [FrameworkErrorDetails] object with the given arguments setting /// the object's properties. /// /// The framework calls this constructor when catching an exception that will - /// subsequently be reported using [UiError.onError]. - const UiErrorDetails({ + /// subsequently be reported using [FrameworkError.onError]. + const FrameworkErrorDetails({ required this.exception, this.stack, this.library = 'Flutter framework', @@ -414,7 +414,7 @@ class UiErrorDetails with Diagnosticable { /// Creates a copy of the error details but with the given fields replaced /// with new values. - UiErrorDetails copyWith({ + FrameworkErrorDetails copyWith({ DiagnosticsNode? context, Object? exception, InformationCollector? informationCollector, @@ -423,7 +423,7 @@ class UiErrorDetails with Diagnosticable { StackTrace? stack, IterableFilter? stackFilter, }) { - return UiErrorDetails( + return FrameworkErrorDetails( context: context ?? this.context, exception: exception ?? this.exception, informationCollector: informationCollector ?? this.informationCollector, @@ -439,7 +439,7 @@ class UiErrorDetails with Diagnosticable { /// into a more descriptive form. /// /// There are layers that attach certain [DiagnosticsNode] into - /// [UiErrorDetails] that require knowledge from other layers to parse. + /// [FrameworkErrorDetails] that require knowledge from other layers to parse. /// To correctly interpret those [DiagnosticsNode], register transformers in /// the layers that possess the knowledge. /// @@ -452,7 +452,7 @@ class UiErrorDetails with Diagnosticable { /// The exception. /// /// Often this will be an [AssertionError], maybe specifically a - /// [UiError]. + /// [FrameworkError]. /// However, this could be any value at all. final Object exception; @@ -464,7 +464,7 @@ class UiErrorDetails with Diagnosticable { /// If this field is not null, then the [stackFilter] callback, if any, will /// be called with the result of calling [toString] on this object and /// splitting that result on line breaks. If there's no [stackFilter] - /// callback, then [UiError.defaultStackFilter] is used instead. That + /// callback, then [FrameworkError.defaultStackFilter] is used instead. That /// function expects the stack to be in the format used by /// [StackTrace.toString]. final StackTrace? stack; @@ -486,7 +486,7 @@ class UiErrorDetails with Diagnosticable { /// /// {@tool snippet} /// This is an example of using and [ErrorDescription] as the - /// [UiErrorDetails.context] when calling [UiError.reportError]. + /// [FrameworkErrorDetails.context] when calling [FrameworkError.reportError]. /// /// ```dart /// void maybeDoSomething() { @@ -514,8 +514,8 @@ class UiErrorDetails with Diagnosticable { /// problem that was detected. /// * [ErrorHint], which provides specific, non-obvious advice that may be /// applicable. - /// * [UiError], which is the most common place to use - /// [UiErrorDetails]. + /// * [FrameworkError], which is the most common place to use + /// [FrameworkErrorDetails]. final DiagnosticsNode? context; /// A callback which filters the [stack] trace. @@ -525,10 +525,10 @@ class UiErrorDetails with Diagnosticable { /// to /// output for the stack. /// - /// If this is not provided, then [UiError.dumpErrorToConsole] will use - /// [UiError.defaultStackFilter] instead. + /// If this is not provided, then [FrameworkError.dumpErrorToConsole] will use + /// [FrameworkError.defaultStackFilter] instead. /// - /// If the [UiError.defaultStackFilter] behavior is desired, then the + /// If the [FrameworkError.defaultStackFilter] behavior is desired, then the /// callback should manually call that function. That function expects the /// incoming list to be in the [StackTrace.toString()] format. The output of /// that function, however, does not always follow this format. @@ -654,11 +654,11 @@ class UiErrorDetails with Diagnosticable { Diagnosticable? _exceptionToDiagnosticable() { final Object exception = this.exception; - if (exception is UiError) { + if (exception is FrameworkError) { return exception; } - if (exception is AssertionError && exception.message is UiError) { - return exception.message! as UiError; + if (exception is AssertionError && exception.message is FrameworkError) { + return exception.message! as FrameworkError; } return null; } @@ -730,7 +730,7 @@ class UiErrorDetails with Diagnosticable { // If so: Error is in Framework. We either need an assertion higher up // in the stack, or we've violated our own assertions. final List stackFrames = - StackFrame.fromStackTrace(UiError.demangleStackTrace(stack!)) + StackFrame.fromStackTrace(FrameworkError.demangleStackTrace(stack!)) .skipWhile((StackFrame frame) => frame.packageScheme == 'dart') .toList(); final bool ourFault = @@ -791,14 +791,9 @@ class UiErrorDetails with Diagnosticable { } } -/// Error class used to report Flutter-specific assertion failures and +/// Error class used to report Framework-specific assertion failures and /// contract violations. -/// -/// See also: -/// -/// * , more information about error -/// handling in Flutter. -class UiError extends Error +class FrameworkError extends Error with DiagnosticableTreeMixin implements AssertionError { /// Create an error message from a string. @@ -809,7 +804,7 @@ class UiError extends Error /// substantial additional information, ideally sufficient to develop a /// correct solution to the problem. /// - /// In some cases, when a [UiError] is reported to the user, only the + /// In some cases, when a [FrameworkError] is reported to the user, only the /// first /// line is included. For example, Flutter will typically only fully report /// the first exception at runtime, displaying only the first line of @@ -823,9 +818,9 @@ class UiError extends Error /// lines are wrapped in implied [ErrorDescription]s. Consider using the /// [FlutterError.fromParts] constructor to provide more detail, e.g. /// using [ErrorHint]s or other [DiagnosticsNode]s. - factory UiError(String message) { + factory FrameworkError(String message) { final List lines = message.split('\n'); - return UiError.fromParts([ + return FrameworkError.fromParts([ ErrorSummary(lines.first), ...lines.skip(1).map(ErrorDescription.new), ]); @@ -882,22 +877,22 @@ class UiError extends Error /// } /// ``` /// {@end-tool} - UiError.fromParts(this.diagnostics) + FrameworkError.fromParts(this.diagnostics) : assert( diagnostics.isNotEmpty, - UiError.fromParts([ + FrameworkError.fromParts([ ErrorSummary('Empty FlutterError'), ]), ) { assert( diagnostics.first.level == DiagnosticLevel.summary, - UiError.fromParts([ + FrameworkError.fromParts([ ErrorSummary('FlutterError is missing a summary.'), ErrorDescription( 'All FlutterError objects should start with a short (one line) ' 'summary description of the problem that was detected.', ), - DiagnosticsProperty( + DiagnosticsProperty( 'Malformed', this, expandableValue: true, @@ -924,7 +919,7 @@ class UiError extends Error '(one line) summary description of the problem that was ' 'detected.', ), - DiagnosticsProperty( + DiagnosticsProperty( 'Malformed', this, expandableValue: true, @@ -954,7 +949,7 @@ class UiError extends Error ' https://github.com/flutter/flutter/issues/new?template=02_bug.yml', ), ); - throw UiError.fromParts(message); + throw FrameworkError.fromParts(message); } return true; }()); @@ -1073,7 +1068,7 @@ class UiError extends Error /// /// The default behavior for the [onError] handler is to call this function. static void dumpErrorToConsole( - UiErrorDetails details, { + FrameworkErrorDetails details, { bool forceReport = false, }) { var isInDebugMode = false; @@ -1132,7 +1127,7 @@ class UiError extends Error /// frames that correspond to Dart internals. /// /// This is the default filter used by [dumpErrorToConsole] if the - /// [UiErrorDetails] object has no [UiErrorDetails.stackFilter] + /// [FrameworkErrorDetails] object has no [FrameworkErrorDetails.stackFilter] /// callback. /// /// This function expects its input to be in the format used by @@ -1269,13 +1264,13 @@ class UiError extends Error /// } /// ``` /// {@end-tool} - static void reportError(UiErrorDetails details) { + static void reportError(FrameworkErrorDetails details) { onError?.call(details); } } /// Dump the stack to the console using [debugPrint] and -/// [UiError.defaultStackFilter]. +/// [FrameworkError.defaultStackFilter]. /// /// If the `stackTrace` parameter is null, the [StackTrace.current] is used to /// obtain the stack. @@ -1292,7 +1287,7 @@ void debugPrintStack({StackTrace? stackTrace, String? label, int? maxFrames}) { if (stackTrace == null) { stackTrace = StackTrace.current; } else { - stackTrace = UiError.demangleStackTrace(stackTrace); + stackTrace = FrameworkError.demangleStackTrace(stackTrace); } Iterable lines = stackTrace.toString().trimRight().split('\n'); if (kIsWeb && lines.isNotEmpty) { @@ -1308,18 +1303,20 @@ void debugPrintStack({StackTrace? stackTrace, String? label, int? maxFrames}) { if (maxFrames != null) { lines = lines.take(maxFrames); } - ErrorToConsoleDumper.dump(UiError.defaultStackFilter(lines).join('\n')); + ErrorToConsoleDumper.dump( + FrameworkError.defaultStackFilter(lines).join('\n'), + ); } /// Diagnostic with a [StackTrace] [value] suitable for displaying stack traces -/// as part of a [UiError] object. +/// as part of a [FrameworkError] object. class DiagnosticsStackTrace extends DiagnosticsBlock { /// Creates a diagnostic for a stack trace. /// /// [name] describes a name the stack trace is given, e.g. /// `When the exception was thrown, this was the stack`. /// [stackFilter] provides an optional filter to use to filter which frames - /// are included. If no filter is specified, [UiError.defaultStackFilter] + /// are included. If no filter is specified, [FrameworkError.defaultStackFilter] /// is used. /// [showSeparator] indicates whether to include a ':' after the [name]. DiagnosticsStackTrace( @@ -1354,9 +1351,9 @@ class DiagnosticsStackTrace extends DiagnosticsBlock { return []; } final IterableFilter filter = - stackFilter ?? UiError.defaultStackFilter; + stackFilter ?? FrameworkError.defaultStackFilter; final Iterable frames = filter( - '${UiError.demangleStackTrace(stack)}'.trimRight().split('\n'), + '${FrameworkError.demangleStackTrace(stack)}'.trimRight().split('\n'), ); return frames.map(_createStackFrame).toList(); } @@ -1369,7 +1366,8 @@ class DiagnosticsStackTrace extends DiagnosticsBlock { bool get allowTruncate => false; } -class _FlutterErrorDetailsNode extends DiagnosticableNode { +class _FlutterErrorDetailsNode + extends DiagnosticableNode { _FlutterErrorDetailsNode({ super.name, required super.value, @@ -1384,7 +1382,7 @@ class _FlutterErrorDetailsNode extends DiagnosticableNode { } Iterable properties = builder.properties; for (final DiagnosticPropertiesTransformer transformer - in UiErrorDetails.propertiesTransformers) { + in FrameworkErrorDetails.propertiesTransformers) { properties = transformer(properties); } return DiagnosticPropertiesBuilder.fromProperties(properties.toList()); diff --git a/packages/ui_primitives/lib/src/foundation/debug.dart b/packages/ui_primitives/lib/src/foundation/debug.dart index 4e1a6ec81..21c39420d 100644 --- a/packages/ui_primitives/lib/src/foundation/debug.dart +++ b/packages/ui_primitives/lib/src/foundation/debug.dart @@ -38,7 +38,7 @@ bool debugAssertAllFoundationVarsUnset( debugDefaultTargetPlatformOverride != null || debugDoublePrecision != null || debugBrightnessOverride != null) { - throw UiError(reason); + throw FrameworkError(reason); } return true; }()); diff --git a/packages/ui_primitives/lib/src/foundation/diagnostics.dart b/packages/ui_primitives/lib/src/foundation/diagnostics.dart index ff2063799..702371e98 100644 --- a/packages/ui_primitives/lib/src/foundation/diagnostics.dart +++ b/packages/ui_primitives/lib/src/foundation/diagnostics.dart @@ -174,7 +174,7 @@ enum DiagnosticsTreeStyle { /// /// See also: /// - /// * [UiError], which uses this style for the root node in a tree + /// * [FrameworkError], which uses this style for the root node in a tree /// describing an error. error, @@ -1681,7 +1681,7 @@ abstract class DiagnosticsNode { // We don't throw in release builds, to avoid hurting users. We also don't // do anything useful. if (kProfileMode) { - throw UiError( + throw FrameworkError( // Parts of this string are searched for verbatim by a test in // dev/bots/test.dart. '$DiagnosticsNode.toTimelineArguments used in non-debug build.\n' diff --git a/packages/ui_primitives/lib/src/foundation/platform.dart b/packages/ui_primitives/lib/src/foundation/platform.dart index a4c3cacf3..b91e0dd74 100644 --- a/packages/ui_primitives/lib/src/foundation/platform.dart +++ b/packages/ui_primitives/lib/src/foundation/platform.dart @@ -108,7 +108,7 @@ TargetPlatform? get debugDefaultTargetPlatformOverride => set debugDefaultTargetPlatformOverride(TargetPlatform? value) { if (!kDebugMode) { - throw UiError( + throw FrameworkError( 'Cannot modify debugDefaultTargetPlatformOverride in non-debug builds.', ); } diff --git a/packages/ui_primitives/lib/src/foundation/value_notifier.dart b/packages/ui_primitives/lib/src/foundation/value_notifier.dart index 0419f1db5..22624eb4b 100644 --- a/packages/ui_primitives/lib/src/foundation/value_notifier.dart +++ b/packages/ui_primitives/lib/src/foundation/value_notifier.dart @@ -94,7 +94,7 @@ class _ChangeNotifier implements Listenable { static bool debugAssertNotDisposed(_ChangeNotifier notifier) { assert(() { if (notifier._debugDisposed) { - throw UiError( + throw FrameworkError( 'A ${notifier.runtimeType} was used after being disposed.\n' 'Once you have called dispose() on a ${notifier.runtimeType}, it ' 'can no longer be used.', @@ -281,7 +281,7 @@ class _ChangeNotifier implements Listenable { /// not be visited after they are removed. /// /// Exceptions thrown by listeners will be caught and reported using - /// [UiError.reportError]. + /// [FrameworkError.reportError]. /// /// This method must not be called after [dispose] has been called. /// @@ -316,8 +316,8 @@ class _ChangeNotifier implements Listenable { try { _listeners[i]?.call(); } catch (exception, stack) { - UiError.reportError( - UiErrorDetails( + FrameworkError.reportError( + FrameworkErrorDetails( exception: exception, stack: stack, library: 'foundation library', @@ -414,7 +414,7 @@ class ValueNotifier implements ValueListenable { static bool debugAssertNotDisposed(ValueNotifier notifier) { assert(() { if (notifier._debugDisposed) { - throw UiError( + throw FrameworkError( 'A ${notifier.runtimeType} was used after being disposed.\n' 'Once you have called dispose() on a ${notifier.runtimeType}, it ' 'can no longer be used.', diff --git a/packages/ui_primitives/lib/ui_primitives.dart b/packages/ui_primitives/lib/ui_primitives.dart index 22efc94af..5fe02dd33 100644 --- a/packages/ui_primitives/lib/ui_primitives.dart +++ b/packages/ui_primitives/lib/ui_primitives.dart @@ -13,8 +13,8 @@ export 'src/foundation/assertions.dart' RepetitiveStackFrameFilter, StackFilter, StackFrame, - UiError, - UiErrorDetails, + FrameworkError, + FrameworkErrorDetails, debugPrintStack; export 'src/foundation/diagnostics.dart' diff --git a/packages/ui_primitives/test/error_reporting_test.dart b/packages/ui_primitives/test/error_reporting_test.dart index 5d042b88a..89a743c88 100644 --- a/packages/ui_primitives/test/error_reporting_test.dart +++ b/packages/ui_primitives/test/error_reporting_test.dart @@ -63,8 +63,8 @@ Future main() async { test('Error reporting - assert with message', () async { expect(console, isEmpty); - UiError.dumpErrorToConsole( - UiErrorDetails( + FrameworkError.dumpErrorToConsole( + FrameworkErrorDetails( exception: getAssertionErrorWithMessage(), stack: sampleStack, library: 'error handling test', @@ -94,21 +94,21 @@ Future main() async { ), ); console.clear(); - UiError.dumpErrorToConsole( - UiErrorDetails(exception: getAssertionErrorWithMessage()), + FrameworkError.dumpErrorToConsole( + FrameworkErrorDetails(exception: getAssertionErrorWithMessage()), ); expect( console.join('\n'), 'Another exception was thrown: Message goes here.', ); console.clear(); - UiError.resetErrorCount(); + FrameworkError.resetErrorCount(); }); test('Error reporting - assert with long message', () async { expect(console, isEmpty); - UiError.dumpErrorToConsole( - UiErrorDetails(exception: getAssertionErrorWithLongMessage()), + FrameworkError.dumpErrorToConsole( + FrameworkErrorDetails(exception: getAssertionErrorWithLongMessage()), ); expect( console.join('\n'), @@ -128,8 +128,8 @@ Future main() async { ), ); console.clear(); - UiError.dumpErrorToConsole( - UiErrorDetails(exception: getAssertionErrorWithLongMessage()), + FrameworkError.dumpErrorToConsole( + FrameworkErrorDetails(exception: getAssertionErrorWithLongMessage()), ); expect( console.join('\n'), @@ -141,13 +141,13 @@ Future main() async { 'word word word word word word word word word word word word word word word word word word word word', ); console.clear(); - UiError.resetErrorCount(); + FrameworkError.resetErrorCount(); }); test('Error reporting - assert with no message', () async { expect(console, isEmpty); - UiError.dumpErrorToConsole( - UiErrorDetails( + FrameworkError.dumpErrorToConsole( + FrameworkErrorDetails( exception: getAssertionErrorWithoutMessage(), stack: sampleStack, library: 'error handling test', @@ -178,8 +178,8 @@ Future main() async { ), ); console.clear(); - UiError.dumpErrorToConsole( - UiErrorDetails(exception: getAssertionErrorWithoutMessage()), + FrameworkError.dumpErrorToConsole( + FrameworkErrorDetails(exception: getAssertionErrorWithoutMessage()), ); expect( console.join('\n'), @@ -190,7 +190,7 @@ Future main() async { ), ); console.clear(); - UiError.resetErrorCount(); + FrameworkError.resetErrorCount(); }); test('Error reporting - NoSuchMethodError', () async { @@ -200,7 +200,9 @@ Future main() async { Invocation.method(#foo, [2, 4]), ); - UiError.dumpErrorToConsole(UiErrorDetails(exception: exception)); + FrameworkError.dumpErrorToConsole( + FrameworkErrorDetails(exception: exception), + ); expect( console.join('\n'), matches( @@ -211,18 +213,22 @@ Future main() async { ), ); console.clear(); - UiError.dumpErrorToConsole(UiErrorDetails(exception: exception)); + FrameworkError.dumpErrorToConsole( + FrameworkErrorDetails(exception: exception), + ); expect( console.join('\n'), 'Another exception was thrown: NoSuchMethodError: int has no foo method accepting arguments (_, _)', ); console.clear(); - UiError.resetErrorCount(); + FrameworkError.resetErrorCount(); }); test('Error reporting - NoSuchMethodError', () async { expect(console, isEmpty); - UiError.dumpErrorToConsole(const UiErrorDetails(exception: 'hello')); + FrameworkError.dumpErrorToConsole( + const FrameworkErrorDetails(exception: 'hello'), + ); expect( console.join('\n'), matches( @@ -233,17 +239,19 @@ Future main() async { ), ); console.clear(); - UiError.dumpErrorToConsole(const UiErrorDetails(exception: 'hello again')); + FrameworkError.dumpErrorToConsole( + const FrameworkErrorDetails(exception: 'hello again'), + ); expect(console.join('\n'), 'Another exception was thrown: hello again'); console.clear(); - UiError.resetErrorCount(); + FrameworkError.resetErrorCount(); }); // Regression test for https://github.com/flutter/flutter/issues/62223 test('Error reporting - empty stack', () async { expect(console, isEmpty); - UiError.dumpErrorToConsole( - UiErrorDetails( + FrameworkError.dumpErrorToConsole( + FrameworkErrorDetails( exception: 'exception - empty stack', stack: StackTrace.fromString(''), ), @@ -260,7 +268,7 @@ Future main() async { ), ); console.clear(); - UiError.resetErrorCount(); + FrameworkError.resetErrorCount(); }); test('Stack traces are not truncated', () async { @@ -278,8 +286,8 @@ Future main() async { #10 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3276:14)'''; expect(console, isEmpty); - UiError.dumpErrorToConsole( - UiErrorDetails( + FrameworkError.dumpErrorToConsole( + FrameworkErrorDetails( exception: AssertionError('Test assertion'), stack: StackTrace.fromString(stackString), ), @@ -305,6 +313,6 @@ When the exception was thrown, this was the stack: ), ); console.clear(); - UiError.resetErrorCount(); + FrameworkError.resetErrorCount(); }); }