diff --git a/packages/flutter_tools/lib/src/commands/debug_adapter.dart b/packages/flutter_tools/lib/src/commands/debug_adapter.dart index 7b495c61d5a..8ebf3f83916 100644 --- a/packages/flutter_tools/lib/src/commands/debug_adapter.dart +++ b/packages/flutter_tools/lib/src/commands/debug_adapter.dart @@ -59,6 +59,14 @@ class DebugAdapterCommand extends FlutterCommand { ipv6: ipv6 ?? false, enableDds: enableDds, test: boolArgDeprecated('test'), + onError: (Object? e) { + globals.printError( + 'Input could not be parsed as a Debug Adapter Protocol message.\n' + 'The "flutter debug-adapter" command is intended for use by tooling ' + 'that communicates using the Debug Adapter Protocol.\n\n' + '$e', + ); + }, ); await server.channel.closed; diff --git a/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart b/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart index f271f259ebf..256c2356eb4 100644 --- a/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart +++ b/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart @@ -28,6 +28,7 @@ class FlutterDebugAdapter extends DartDebugAdapter> collectAllOutput({ String? program, String? cwd, - Future Function()? start, + Future Function()? start, Future Function()? launch, bool skipInitialPubGetOutput = true }) async { diff --git a/packages/flutter_tools/test/integration.shard/debug_adapter/test_server.dart b/packages/flutter_tools/test/integration.shard/debug_adapter/test_server.dart index 43be68bf420..f92da208d41 100644 --- a/packages/flutter_tools/test/integration.shard/debug_adapter/test_server.dart +++ b/packages/flutter_tools/test/integration.shard/debug_adapter/test_server.dart @@ -19,6 +19,7 @@ abstract class DapTestServer { Future stop(); StreamSink> get sink; Stream> get stream; + Function(String message)? onStderrOutput; } /// An instance of a DAP server running in-process (to aid debugging). @@ -73,22 +74,27 @@ class OutOfProcessDapTestServer extends DapTestServer { this._process, Logger? logger, ) { - // Treat anything written to stderr as the DAP crashing and fail the test - // unless it's "Waiting for another flutter command to release the startup - // lock" or we're tearing down. + // Unless we're given an error handler, treat anything written to stderr as + // the DAP crashing and fail the test unless it's "Waiting for another + // flutter command to release the startup lock" or we're tearing down. _process.stderr .transform(utf8.decoder) .where((String error) => !error.contains('Waiting for another flutter command to release the startup lock')) .listen((String error) { logger?.call(error); if (!_isShuttingDown) { - throw Exception(error); + final Function(String message)? stderrHandler = onStderrOutput; + if (stderrHandler != null) { + stderrHandler(error); + } else { + throw Exception(error); + } } }); unawaited(_process.exitCode.then((int code) { final String message = 'Out-of-process DAP server terminated with code $code'; logger?.call(message); - if (!_isShuttingDown && code != 0) { + if (!_isShuttingDown && code != 0 && onStderrOutput == null) { throw Exception(message); } })); @@ -97,6 +103,8 @@ class OutOfProcessDapTestServer extends DapTestServer { bool _isShuttingDown = false; final Process _process; + Future get exitCode => _process.exitCode; + @override StreamSink> get sink => _process.stdin;