Skip to content

Support DAP exceptionOptions for catching arbitrary exception classes - #1183

Open
rira100000000 wants to merge 1 commit into
ruby:masterfrom
rira100000000:dap-exception-options
Open

Support DAP exceptionOptions for catching arbitrary exception classes#1183
rira100000000 wants to merge 1 commit into
ruby:masterfrom
rira100000000:dap-exception-options

Conversation

@rira100000000

Copy link
Copy Markdown

Description

Fixes #1182

The console UI can catch arbitrary exception classes (catch MyError),
but the DAP implementation only exposed two fixed filters: 'any'
(Exception) and 'RuntimeError'. Filter conditions are evaluated in the
binding of the raise site and cannot access the raised exception, so
they are no substitute for class filtering either.

Implement the DAP standard exceptionOptions argument of
setExceptionBreakpoints (capability: supportsExceptionOptions), which
was already listed under "Will be supported". Class names given via
ExceptionPathSegment are registered as catch breakpoints using the
same ancestor class-name matching as the console catch command, so
subclasses are caught as well.

  • breakMode 'never' registers nothing. The others all break at raise,
    since Ruby's catch breakpoints fire when an exception is raised and
    DAP provides no way for an adapter to tell the client which
    breakModes it supports.
  • negate path segments are not supported for now and are reported as
    unverified.
  • Class names registered via exceptionOptions are remembered so that
    the next setExceptionBreakpoints request replaces them, as the DAP
    spec requires.

Example

This request makes the debuggee stop where MyError (or a subclass of it) is raised:

{
  "command": "setExceptionBreakpoints",
  "arguments": {
    "filters": [],
    "exceptionOptions": [
      { "path": [{ "names": ["MyError"] }], "breakMode": "always" }
    ]
  }
}

Tests

Added protocol tests in test/protocol/catch_test.rb:

  • a specific exception class (and its subclass) is caught via exceptionOptions
  • breakMode never does not register a breakpoint
  • breakpoints are replaced by the next setExceptionBreakpoints request
  • negated path segments are reported as unverified

I also verified the behavior manually by sending raw DAP requests to rdbg --open over a UNIX domain socket.

The console UI can catch arbitrary exception classes (catch MyError),
but the DAP implementation only exposed two fixed filters: 'any'
(Exception) and 'RuntimeError'. Filter conditions are evaluated in the
binding of the raise site and cannot access the raised exception, so
they are no substitute for class filtering either.

Implement the DAP standard exceptionOptions argument of
setExceptionBreakpoints (capability: supportsExceptionOptions), which
was already listed under "Will be supported". Class names given via
ExceptionPathSegment are registered as catch breakpoints using the
same ancestor class-name matching as the console catch command, so
subclasses are caught as well.

- breakMode 'never' registers nothing. The others all break at raise,
  since Ruby's catch breakpoints fire when an exception is raised and
  DAP provides no way for an adapter to tell the client which
  breakModes it supports.
- negate path segments are not supported for now and are reported as
  unverified.
- Class names registered via exceptionOptions are remembered so that
  the next setExceptionBreakpoints request replaces them, as the DAP
  spec requires.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support exceptionOptions in setExceptionBreakpoints to catch arbitrary exception classes via DAP

1 participant