Prevent `flutter_tools` crash when the Dart execution context cannot be found (#1642)
diff --git a/dwds/lib/src/debugging/execution_context.dart b/dwds/lib/src/debugging/execution_context.dart
index 9adb739..ba7ff1a 100644
--- a/dwds/lib/src/debugging/execution_context.dart
+++ b/dwds/lib/src/debugging/execution_context.dart
@@ -30,8 +30,13 @@
Future<int> get id async {
if (_id != null) return _id;
_logger.fine('Looking for Dart execution context...');
+ const timeoutInMs = 100;
while (await _contexts.hasNext
- .timeout(const Duration(milliseconds: 50), onTimeout: () => false)) {
+ .timeout(const Duration(milliseconds: timeoutInMs), onTimeout: () {
+ _logger.warning(
+ 'Timed out finding an execution context after $timeoutInMs ms.');
+ return false;
+ })) {
final context = await _contexts.next;
_logger.fine('Checking context id: $context');
try {
diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart
index fcc952e..bc76be1 100644
--- a/dwds/lib/src/debugging/inspector.dart
+++ b/dwds/lib/src/debugging/inspector.dart
@@ -173,7 +173,15 @@
return appInspector;
}
- Future<int> get contextId => _executionContext.id;
+ /// Returns the ID for the execution context or null if not found.
+ Future<int> get contextId async {
+ try {
+ return await _executionContext.id;
+ } catch (e, s) {
+ _logger.severe('Missing execution context ID: ', e, s);
+ return null;
+ }
+ }
/// Get the value of the field named [fieldName] from [receiver].
Future<RemoteObject> loadField(RemoteObject receiver, String fieldName) {
@@ -548,14 +556,23 @@
Future<List<String>> _getExtensionRpcs() async {
final expression =
"${globalLoadStrategy.loadModuleSnippet}('dart_sdk').developer._extensions.keys.toList();";
- final extensionsResult =
- await remoteDebugger.sendCommand('Runtime.evaluate', params: {
+ final extensionRpcs = <String>[];
+ final params = {
'expression': expression,
'returnByValue': true,
'contextId': await contextId,
- });
- handleErrorIfPresent(extensionsResult, evalContents: expression);
- return List.from(extensionsResult.result['result']['value'] as List);
+ };
+ try {
+ final extensionsResult =
+ await remoteDebugger.sendCommand('Runtime.evaluate', params: params);
+ handleErrorIfPresent(extensionsResult, evalContents: expression);
+ extensionRpcs.addAll(
+ List.from(extensionsResult.result['result']['value'] as List));
+ } catch (e, s) {
+ _logger.severe(
+ 'Error calling Runtime.evaluate with params $params', e, s);
+ }
+ return extensionRpcs;
}
/// Convert a JS exception description into a description containing