Skip to content

Commit 36548d1

Browse files
committed
Be very careful when invoking the build script via isolate
Closes #10
1 parent 73f2d59 commit 36548d1

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

webdev/lib/src/command/build_runner_command_base.dart

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'dart:io';
77
import 'dart:isolate';
88

99
import 'package:args/command_runner.dart';
10+
import 'package:stack_trace/stack_trace.dart';
1011

1112
/// Extend to get a command with the arguments common to all build_runner
1213
/// commands.
@@ -26,10 +27,41 @@ abstract class BuildRunnerCommandBase extends Command {
2627

2728
Future runCore(String command) async {
2829
final arguments = [command]..addAll(argResults.arguments);
30+
31+
// Heavily inspired by dart-lang/build @ 0c77443dd7
32+
// /build_runner/bin/build_runner.dart#L58-L85
2933
var exitPort = new ReceivePort();
30-
await Isolate.spawnUri(await _buildRunnerScript(), arguments, null,
31-
onExit: exitPort.sendPort, automaticPackageResolution: true);
34+
var errorPort = new ReceivePort();
35+
var messagePort = new ReceivePort();
36+
var errorListener = errorPort.listen((e) {
37+
stderr.writeln('\n\nYou have hit a bug in build_runner');
38+
stderr.writeln('Please file an issue with reproduction steps at '
39+
'https://github.com/dart-lang/build/issues\n\n');
40+
final error = e[0];
41+
final trace = e[1] as String;
42+
stderr.writeln(error);
43+
stderr.writeln(new Trace.parse(trace).terse);
44+
if (exitCode == 0) exitCode = 1;
45+
});
46+
await Isolate.spawnUri(
47+
await _buildRunnerScript(), arguments, messagePort.sendPort,
48+
onExit: exitPort.sendPort,
49+
onError: errorPort.sendPort,
50+
automaticPackageResolution: true);
51+
StreamSubscription exitCodeListener;
52+
exitCodeListener = messagePort.listen((isolateExitCode) {
53+
if (isolateExitCode is! int) {
54+
throw new StateError(
55+
'Bad response from isolate, expected an exit code but got '
56+
'$isolateExitCode');
57+
}
58+
exitCode = isolateExitCode as int;
59+
exitCodeListener.cancel();
60+
exitCodeListener = null;
61+
});
3262
await exitPort.first;
63+
await errorListener.cancel();
64+
await exitCodeListener?.cancel();
3365
}
3466
}
3567

webdev/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ environment:
1010
dependencies:
1111
args: ^1.2.0
1212
io: ^0.3.2+1
13+
stack_trace: ^1.9.2
1314

1415
executables:
1516
webdev:

0 commit comments

Comments
 (0)