From 3d39175f5db774123d4886ec00a5d6d1de7e13aa Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Wed, 22 Feb 2023 17:11:12 +0000 Subject: [PATCH] [dds/dap] Improve display of errors calling toString() in debug views Fixes https://github.com/Dart-Code/Dart-Code/issues/4400. Change-Id: I46b36bcacdd0f8a33f296569fbc2e4ebece9d0f4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/284701 Reviewed-by: Ben Konyi Commit-Queue: Ben Konyi --- pkg/dds/lib/src/dap/protocol_converter.dart | 5 +++ .../dap/integration/debug_variables_test.dart | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/pkg/dds/lib/src/dap/protocol_converter.dart b/pkg/dds/lib/src/dap/protocol_converter.dart index dacb1a3e2f0..863026f3a99 100644 --- a/pkg/dds/lib/src/dap/protocol_converter.dart +++ b/pkg/dds/lib/src/dap/protocol_converter.dart @@ -369,6 +369,11 @@ class ProtocolConverter { allowCallingToString: allowCallingToString, format: format, ); + } else if (response is vm.ErrorRef) { + final errorMessage = response.message; + return errorMessage != null + ? _adapter.extractUnhandledExceptionMessage(errorMessage) + : response.kind ?? ''; } else if (response is vm.Sentinel) { return ''; } else { diff --git a/pkg/dds/test/dap/integration/debug_variables_test.dart b/pkg/dds/test/dap/integration/debug_variables_test.dart index a8992bdf569..b221d4dfe6b 100644 --- a/pkg/dds/test/dap/integration/debug_variables_test.dart +++ b/pkg/dds/test/dap/integration/debug_variables_test.dart @@ -577,6 +577,38 @@ void main() { ); }); + test('handles errors in toString() on custom classes', () async { + final client = dap.client; + final testFile = dap.createTestFile(''' +class Foo { + toString() => throw UnimplementedError('NYI!'); +} + +void main() { + final myVariable = Foo(); + print('Hello!'); $breakpointMarker +} + '''); + final breakpointLine = lineWith(testFile, breakpointMarker); + + final stop = await client.hitBreakpoint( + testFile, + breakpointLine, + launch: () => client.launch( + testFile.path, + evaluateToStringInDebugViews: true, + ), + ); + + await client.expectScopeVariables( + await client.getTopFrameId(stop.threadId!), + 'Locals', + r''' + myVariable: Foo (UnimplementedError: NYI!), eval: myVariable + ''', + ); + }); + test('does not use toString() result if "Instance of Foo"', () async { // When evaluateToStringInDebugViews=true, we should discard the result of // calling toString() when it's just 'Instance of Foo' because we're already