Unverified Commit 3b4ab4eb authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Throw error when hot reload enters bad state (#38907)

parent 1ff30fbb
...@@ -98,14 +98,45 @@ class StdoutHandler { ...@@ -98,14 +98,45 @@ class StdoutHandler {
bool _suppressCompilerMessages; bool _suppressCompilerMessages;
bool _expectSources; bool _expectSources;
bool _badState = false;
void handler(String message) { void handler(String message) {
printTrace('-> $message'); printTrace('-> $message');
if (_badState) {
return;
}
const String kResultPrefix = 'result '; const String kResultPrefix = 'result ';
if (boundaryKey == null && message.startsWith(kResultPrefix)) { if (boundaryKey == null && message.startsWith(kResultPrefix)) {
boundaryKey = message.substring(kResultPrefix.length); boundaryKey = message.substring(kResultPrefix.length);
return; return;
} }
// Invalid state, see commented issue below for more information.
// NB: both the completeError and _badState flags are required to avoid
// filling the console with exceptions.
if (boundaryKey == null) {
// Throwing a synchronous exception via throwToolExit will fail to cancel
// the stream. Instead use completeError so that the error is returned
// from the awaited future that the compiler consumers are expecting.
compilerOutput.completeError(ToolExit(
'The Dart compiler encountered an internal problem. '
'The Flutter team would greatly appreciate if you could leave a '
'comment on the issue https://github.com/flutter/flutter/issues/35924 '
'describing what you were doing when the crash happened.\n\n'
'Additional debugging information:\n'
' StdoutState: $state\n'
' compilerMessageReceived: $compilerMessageReceived\n'
' _expectSources: $_expectSources\n'
' sources: $sources\n'
));
// There are several event turns before the tool actually exits from a
// tool exception. Normally, the stream should be cancelled to prevent
// more events from entering the bad state, but because the error
// is coming from handler itself, there is no clean way to pipe this
// through. Instead, we set a flag to prevent more messages from
// registering.
_badState = true;
return;
}
if (message.startsWith(boundaryKey)) { if (message.startsWith(boundaryKey)) {
if (_expectSources) { if (_expectSources) {
if (state == StdoutState.CollectDiagnostic) { if (state == StdoutState.CollectDiagnostic) {
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/compile.dart'; import 'package:flutter_tools/src/compile.dart';
import '../src/common.dart'; import '../src/common.dart';
...@@ -19,6 +20,14 @@ void main() { ...@@ -19,6 +20,14 @@ void main() {
expect(output.outputFilename, 'message'); expect(output.outputFilename, 'message');
}); });
testUsingContext('StdOutHandler crash test', () async {
final StdoutHandler stdoutHandler = StdoutHandler();
final Future<CompilerOutput> output = stdoutHandler.compilerOutput.future;
stdoutHandler.handler('message with no result');
expect(output, throwsA(isInstanceOf<ToolExit>()));
});
test('TargetModel values', () { test('TargetModel values', () {
expect(TargetModel('vm'), TargetModel.vm); expect(TargetModel('vm'), TargetModel.vm);
expect(TargetModel.vm.toString(), 'vm'); expect(TargetModel.vm.toString(), 'vm');
......
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