mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Print errors in all build modes (#69046)
This commit is contained in:
parent
2e54c4a8ea
commit
7a10b46ee0
@ -776,9 +776,12 @@ Future<void> _runWebUnitTests() async {
|
||||
}
|
||||
|
||||
Future<void> _runWebIntegrationTests() async {
|
||||
await _runWebStackTraceTest('profile');
|
||||
await _runWebStackTraceTest('release');
|
||||
await _runWebStackTraceTest('profile', 'lib/stack_trace.dart');
|
||||
await _runWebStackTraceTest('release', 'lib/stack_trace.dart');
|
||||
await _runWebStackTraceTest('profile', 'lib/framework_stack_trace.dart');
|
||||
await _runWebStackTraceTest('release', 'lib/framework_stack_trace.dart');
|
||||
await _runWebDebugTest('lib/stack_trace.dart');
|
||||
await _runWebDebugTest('lib/framework_stack_trace.dart');
|
||||
await _runWebDebugTest('lib/web_directory_loading.dart');
|
||||
await _runWebDebugTest('test/test.dart');
|
||||
await _runWebDebugTest('lib/null_assert_main.dart', enableNullSafety: true);
|
||||
@ -807,7 +810,7 @@ Future<void> _runWebIntegrationTests() async {
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> _runWebStackTraceTest(String buildMode) async {
|
||||
Future<void> _runWebStackTraceTest(String buildMode, String entrypoint) async {
|
||||
final String testAppDirectory = path.join(flutterRoot, 'dev', 'integration_tests', 'web');
|
||||
final String appBuildDirectory = path.join(testAppDirectory, 'build', 'web');
|
||||
|
||||
@ -824,7 +827,7 @@ Future<void> _runWebStackTraceTest(String buildMode) async {
|
||||
'web',
|
||||
'--$buildMode',
|
||||
'-t',
|
||||
'lib/stack_trace.dart',
|
||||
entrypoint,
|
||||
],
|
||||
workingDirectory: testAppDirectory,
|
||||
environment: <String, String>{
|
||||
|
96
dev/integration_tests/web/lib/framework_stack_trace.dart
Normal file
96
dev/integration_tests/web/lib/framework_stack_trace.dart
Normal file
@ -0,0 +1,96 @@
|
||||
// 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.
|
||||
|
||||
import 'dart:html' as html;
|
||||
|
||||
import 'package:meta/dart2js.dart';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
// Tests that the framework prints stack traces in all build modes.
|
||||
//
|
||||
// Regression test for https://github.com/flutter/flutter/issues/68616.
|
||||
//
|
||||
// See also `dev/integration_tests/web/lib/stack_trace.dart` that tests the
|
||||
// framework's ability to parse stack traces in all build modes.
|
||||
void main() async {
|
||||
final StringBuffer errorMessage = StringBuffer();
|
||||
debugPrint = (String message, { int wrapWidth }) {
|
||||
errorMessage.writeln(message);
|
||||
};
|
||||
|
||||
runApp(ThrowingWidget());
|
||||
|
||||
// Let the framework flush error messages.
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
|
||||
final StringBuffer output = StringBuffer();
|
||||
if (_errorMessageFormattedCorrectly(errorMessage.toString())) {
|
||||
output.writeln('--- TEST SUCCEEDED ---');
|
||||
} else {
|
||||
output.writeln('--- UNEXPECTED ERROR MESSAGE FORMAT ---');
|
||||
output.writeln(errorMessage);
|
||||
output.writeln('--- TEST FAILED ---');
|
||||
}
|
||||
|
||||
print(output);
|
||||
html.HttpRequest.request(
|
||||
'/test-result',
|
||||
method: 'POST',
|
||||
sendData: '$output',
|
||||
);
|
||||
}
|
||||
|
||||
bool _errorMessageFormattedCorrectly(String errorMessage) {
|
||||
if (!errorMessage.contains('Test error message')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In release mode symbols are minified. No sense testing the contents of the stack trace.
|
||||
if (kReleaseMode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const List<String> expectedFunctions = <String>[
|
||||
'topLevelFunction',
|
||||
'secondLevelFunction',
|
||||
'thirdLevelFunction',
|
||||
];
|
||||
|
||||
return expectedFunctions.every(errorMessage.contains);
|
||||
}
|
||||
|
||||
class ThrowingWidget extends StatefulWidget {
|
||||
@override
|
||||
_ThrowingWidgetState createState() => _ThrowingWidgetState();
|
||||
}
|
||||
|
||||
class _ThrowingWidgetState extends State<ThrowingWidget> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
topLevelFunction();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
@noInline
|
||||
void topLevelFunction() {
|
||||
secondLevelFunction();
|
||||
}
|
||||
|
||||
@noInline
|
||||
void secondLevelFunction() {
|
||||
thirdLevelFunction();
|
||||
}
|
||||
|
||||
@noInline
|
||||
void thirdLevelFunction() {
|
||||
throw Exception('Test error message');
|
||||
}
|
@ -944,22 +944,32 @@ class FlutterError extends Error with DiagnosticableTreeMixin implements Asserti
|
||||
static void dumpErrorToConsole(FlutterErrorDetails details, { bool forceReport = false }) {
|
||||
assert(details != null);
|
||||
assert(details.exception != null);
|
||||
bool reportError = details.silent != true; // could be null
|
||||
bool isInDebugMode = false;
|
||||
assert(() {
|
||||
// In checked mode, we ignore the "silent" flag.
|
||||
reportError = true;
|
||||
isInDebugMode = true;
|
||||
return true;
|
||||
}());
|
||||
final bool reportError = isInDebugMode || details.silent != true; // could be null
|
||||
if (!reportError && !forceReport)
|
||||
return;
|
||||
if (_errorCount == 0 || forceReport) {
|
||||
debugPrint(
|
||||
TextTreeRenderer(
|
||||
wrapWidth: wrapWidth,
|
||||
wrapWidthProperties: wrapWidth,
|
||||
maxDescendentsTruncatableNode: 5,
|
||||
).render(details.toDiagnosticsNode(style: DiagnosticsTreeStyle.error)).trimRight(),
|
||||
);
|
||||
// Diagnostics is only available in debug mode. In profile and release modes fallback to plain print.
|
||||
if (isInDebugMode) {
|
||||
debugPrint(
|
||||
TextTreeRenderer(
|
||||
wrapWidth: wrapWidth,
|
||||
wrapWidthProperties: wrapWidth,
|
||||
maxDescendentsTruncatableNode: 5,
|
||||
).render(details.toDiagnosticsNode(style: DiagnosticsTreeStyle.error)).trimRight(),
|
||||
);
|
||||
} else {
|
||||
debugPrintStack(
|
||||
stackTrace: details.stack,
|
||||
label: details.exception.toString(),
|
||||
maxFrames: 100,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
debugPrint('Another exception was thrown: ${details.summary}');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user