Add support for breaking on exceptions and pausing R at any time#1036
Open
Add support for breaking on exceptions and pausing R at any time#1036
Conversation
4611c2c to
dbb841c
Compare
afd3936 to
7f71cca
Compare
1811c21 to
fb0490c
Compare
Contributor
Author
|
I've added some filtering of condition handling/emitting frames, like |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Branched from #1033 (for test infra)
Addresses posit-dev/positron#11797
Addresses posit-dev/positron#11799
Adds support for the DAP feature of exception breakpoints, and for pausing the debugger at any time. Both features rely on:
Calling
browser()from a global handler for the relevant condition (error, warning, or interrupt)Skipping the top-level frame which points to our global handlers.
When these handlers trigger, the R stack includes the handler frame at the top. Since this frame is not useful to users, we track why we entered the debugger via
DebugStoppedReason(Conditionfor errors/warnings,Pausefor interrupts) and discard the top frame instart_debug()for these cases.Note that the console will still evaluate in this frame until we fix IDE alternative to
options(error = recover)positron#9156 (comment).Also note that for errors and warnings, we'd ideally automatically skip the part of the call stack involved in emitting/handling the condition (partly the base emitting context with
withRestart()etc, and partly the package-level emitting context, e.g. based on rlang'serror_call = parent.frame()pattern).The condition breakpoints are surfaced like this in the UI:
We could add messages as well but I thought that'd crowd the UI, and it doesn't feel as useful to easily break on those. Could be added as a user setting in the future.
Pausing can be done by calling the existing VS Code command "Pause":
QA Notes
This is comprehensively tested on the backend side.
Exception breakpoints (break on error/warning):
In the Debug Console's breakpoint picker, enable "Uncaught Errors" or "Warnings".
Run code that triggers an error (e.g.
stop("oops")) or warning (e.g.warning("hmm")). The debugger should pause at the point of the condition.The call stack should show user code (for errors or warnings thrown from C) or
stop()/warning(), not R's internal condition handling frames (.handleSimpleError,doWithOneRestart, etc.).The exception type and message should appear in the editor and the debug UI (e.g. "simpleError: oops").
Continue (
c) should resume execution and propagate the error/warning normally.Pause:
While R is executing a long-running operation (e.g.
Sys.sleep(100), an infinite loop, or I/O), run theDebug: Pausecommand from the command palette. R should interrupt and drop into the debugger at the current execution point.The call stack should reflect where R was interrupted.
Qshould exit the debugger.c/ Continue should resume running code. Note that with curl downloads or I/O there are known issues.