Commit aac8762a authored by Todd Volkert's avatar Todd Volkert Committed by GitHub

Properly handle `ProcessExit` being thrown when `exit()` is called (#8592)

parent 96ccad53
...@@ -182,7 +182,12 @@ Future<int> _handleToolError( ...@@ -182,7 +182,12 @@ Future<int> _handleToolError(
return _exit(error.exitCode ?? 1); return _exit(error.exitCode ?? 1);
} else if (error is ProcessExit) { } else if (error is ProcessExit) {
// We've caught an exit code. // We've caught an exit code.
return _exit(error.exitCode); if (error.immediate) {
exit(error.exitCode);
return error.exitCode;
} else {
return _exit(error.exitCode);
}
} else { } else {
// We've crashed; emit a log report. // We've crashed; emit a log report.
stderr.writeln(); stderr.writeln();
...@@ -217,7 +222,11 @@ Future<int> _handleToolError( ...@@ -217,7 +222,11 @@ Future<int> _handleToolError(
'Unable to generate crash report due to secondary error: $error\n' 'Unable to generate crash report due to secondary error: $error\n'
'please let us know at https://github.com/flutter/flutter/issues.', 'please let us know at https://github.com/flutter/flutter/issues.',
); );
return _exit(1); // Any exception throw here (including one thrown by `_exit()`) will
// get caught by our zone's `onError` handler. In order to avoid an
// infinite error loop, we throw an error that is recognized above
// and will trigger an immediate exit.
throw new ProcessExit(1, immediate: true);
} }
} }
} }
...@@ -299,9 +308,13 @@ Future<int> _exit(int code) async { ...@@ -299,9 +308,13 @@ Future<int> _exit(int code) async {
// Give the task / timer queue one cycle through before we hard exit. // Give the task / timer queue one cycle through before we hard exit.
Timer.run(() { Timer.run(() {
printTrace('exiting with code $code'); try {
exit(code); printTrace('exiting with code $code');
completer.complete(); exit(code);
completer.complete();
} catch (error, stackTrace) {
completer.completeError(error, stackTrace);
}
}); });
await completer.future; await completer.future;
......
...@@ -25,10 +25,12 @@ ...@@ -25,10 +25,12 @@
/// about any additional exports that you add to this file, as doing so will /// about any additional exports that you add to this file, as doing so will
/// increase the API surface that we have to test in Flutter tools, and the APIs /// increase the API surface that we have to test in Flutter tools, and the APIs
/// in `dart:io` can sometimes be hard to use in tests. /// in `dart:io` can sometimes be hard to use in tests.
import 'dart:io' as io show exit, exitCode; import 'dart:io' as io show exit;
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'process.dart';
export 'dart:io' export 'dart:io'
show show
BytesBuilder, BytesBuilder,
...@@ -88,7 +90,7 @@ ExitFunction get exit => _exitFunction; ...@@ -88,7 +90,7 @@ ExitFunction get exit => _exitFunction;
@visibleForTesting @visibleForTesting
void setExitFunctionForTests([ExitFunction exitFunction]) { void setExitFunctionForTests([ExitFunction exitFunction]) {
_exitFunction = exitFunction ?? (int exitCode) { _exitFunction = exitFunction ?? (int exitCode) {
throw new Exception('Exited with code ${io.exitCode}'); throw new ProcessExit(exitCode, immediate: true);
}; };
} }
......
...@@ -295,8 +295,9 @@ String _runWithLoggingSync(List<String> cmd, { ...@@ -295,8 +295,9 @@ String _runWithLoggingSync(List<String> cmd, {
} }
class ProcessExit implements Exception { class ProcessExit implements Exception {
ProcessExit(this.exitCode); ProcessExit(this.exitCode, {this.immediate: false});
final bool immediate;
final int exitCode; final int exitCode;
String get message => 'ProcessExit: $exitCode'; String get message => 'ProcessExit: $exitCode';
......
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