Unverified Commit f9c58bea authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] also listen to web stderr stream (#53949)

parent f5fe1e3e
...@@ -107,6 +107,7 @@ abstract class ResidentWebRunner extends ResidentRunner { ...@@ -107,6 +107,7 @@ abstract class ResidentWebRunner extends ResidentRunner {
ConnectionResult _connectionResult; ConnectionResult _connectionResult;
StreamSubscription<vmservice.Event> _stdOutSub; StreamSubscription<vmservice.Event> _stdOutSub;
StreamSubscription<vmservice.Event> _stdErrSub;
bool _exited = false; bool _exited = false;
WipConnection _wipConnection; WipConnection _wipConnection;
...@@ -143,6 +144,7 @@ abstract class ResidentWebRunner extends ResidentRunner { ...@@ -143,6 +144,7 @@ abstract class ResidentWebRunner extends ResidentRunner {
return; return;
} }
await _stdOutSub?.cancel(); await _stdOutSub?.cancel();
await _stdErrSub?.cancel();
await device.device.stopApp(null); await device.device.stopApp(null);
try { try {
_generatedEntrypointDirectory?.deleteSync(recursive: true); _generatedEntrypointDirectory?.deleteSync(recursive: true);
...@@ -652,16 +654,14 @@ class _ResidentWebRunner extends ResidentWebRunner { ...@@ -652,16 +654,14 @@ class _ResidentWebRunner extends ResidentWebRunner {
_connectionResult = await webDevFS.connect(useDebugExtension); _connectionResult = await webDevFS.connect(useDebugExtension);
unawaited(_connectionResult.debugConnection.onDone.whenComplete(_cleanupAndExit)); unawaited(_connectionResult.debugConnection.onDone.whenComplete(_cleanupAndExit));
// Cleanup old subscriptions. These will throw if there isn't anything
// listening, which is fine because that is what we want to ensure.
try { try {
await _vmService.streamCancel(vmservice.EventStreams.kStdout); await _vmService.streamListen(vmservice.EventStreams.kStdout);
} on vmservice.RPCError { } on vmservice.RPCError {
// It is safe to ignore this error because we expect an error to be // It is safe to ignore this error because we expect an error to be
// thrown if we're not already subscribed. // thrown if we're not already subscribed.
} }
try { try {
await _vmService.streamListen(vmservice.EventStreams.kStdout); await _vmService.streamListen(vmservice.EventStreams.kStderr);
} on vmservice.RPCError { } on vmservice.RPCError {
// It is safe to ignore this error because we expect an error to be // It is safe to ignore this error because we expect an error to be
// thrown if we're not already subscribed. // thrown if we're not already subscribed.
...@@ -674,7 +674,11 @@ class _ResidentWebRunner extends ResidentWebRunner { ...@@ -674,7 +674,11 @@ class _ResidentWebRunner extends ResidentWebRunner {
} }
_stdOutSub = _vmService.onStdoutEvent.listen((vmservice.Event log) { _stdOutSub = _vmService.onStdoutEvent.listen((vmservice.Event log) {
final String message = utf8.decode(base64.decode(log.bytes)); final String message = utf8.decode(base64.decode(log.bytes));
globals.printStatus(message); globals.printStatus(message, newline: false);
});
_stdErrSub = _vmService.onStderrEvent.listen((vmservice.Event log) {
final String message = utf8.decode(base64.decode(log.bytes));
globals.printStatus(message, newline: false);
}); });
unawaited(_vmService.registerService('reloadSources', 'FlutterTools')); unawaited(_vmService.registerService('reloadSources', 'FlutterTools'));
_vmService.registerServiceCallback('reloadSources', (Map<String, Object> params) async { _vmService.registerServiceCallback('reloadSources', (Map<String, Object> params) async {
......
...@@ -116,6 +116,9 @@ void main() { ...@@ -116,6 +116,9 @@ void main() {
when(mockVmService.onStdoutEvent).thenAnswer((Invocation _) { when(mockVmService.onStdoutEvent).thenAnswer((Invocation _) {
return const Stream<Event>.empty(); return const Stream<Event>.empty();
}); });
when(mockVmService.onStderrEvent).thenAnswer((Invocation _) {
return const Stream<Event>.empty();
});
when(mockVmService.onDebugEvent).thenAnswer((Invocation _) { when(mockVmService.onDebugEvent).thenAnswer((Invocation _) {
return const Stream<Event>.empty(); return const Stream<Event>.empty();
}); });
...@@ -249,20 +252,30 @@ void main() { ...@@ -249,20 +252,30 @@ void main() {
expect(await residentWebRunner.run(), 0); expect(await residentWebRunner.run(), 0);
})); }));
test('Listens to stdout streams before running main', () => testbed.run(() async { test('Listens to stdout and stderr streams before running main', () => testbed.run(() async {
_setupMocks(); _setupMocks();
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>(); final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
final StreamController<Event> controller = StreamController<Event>.broadcast(); final StreamController<Event> stdoutController = StreamController<Event>.broadcast();
final StreamController<Event> stderrController = StreamController<Event>.broadcast();
when(mockVmService.onStdoutEvent).thenAnswer((Invocation _) { when(mockVmService.onStdoutEvent).thenAnswer((Invocation _) {
return controller.stream; return stdoutController.stream;
});
when(mockVmService.onStderrEvent).thenAnswer((Invocation _) {
return stderrController.stream;
}); });
when(mockAppConnection.runMain()).thenAnswer((Invocation invocation) { when(mockAppConnection.runMain()).thenAnswer((Invocation invocation) {
controller.add(Event.parse(<String, Object>{ stdoutController.add(Event.parse(<String, Object>{
'type': 'Event', 'type': 'Event',
'kind': 'WriteEvent', 'kind': 'WriteEvent',
'timestamp': 1569473488296, 'timestamp': 1569473488296,
'bytes': base64.encode('THIS MESSAGE IS IMPORTANT'.codeUnits), 'bytes': base64.encode('THIS MESSAGE IS IMPORTANT'.codeUnits),
})); }));
stderrController.add(Event.parse(<String, Object>{
'type': 'Event',
'kind': 'WriteEvent',
'timestamp': 1569473488296,
'bytes': base64.encode('SO IS THIS'.codeUnits),
}));
}); });
unawaited(residentWebRunner.run( unawaited(residentWebRunner.run(
connectionInfoCompleter: connectionInfoCompleter, connectionInfoCompleter: connectionInfoCompleter,
...@@ -270,6 +283,7 @@ void main() { ...@@ -270,6 +283,7 @@ void main() {
await connectionInfoCompleter.future; await connectionInfoCompleter.future;
expect(testLogger.statusText, contains('THIS MESSAGE IS IMPORTANT')); expect(testLogger.statusText, contains('THIS MESSAGE IS IMPORTANT'));
expect(testLogger.statusText, contains('SO IS THIS'));
})); }));
test('Does not run main with --start-paused', () => testbed.run(() async { test('Does not run main with --start-paused', () => testbed.run(() async {
......
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