-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't use a restart to handle stop_on_error = 2L #232
base: main
Are you sure you want to change the base?
Conversation
In this case, the handler could simply return NULL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for diving into this problem and figuring out a fix!
I think my only suggestion would be to make the snapshot a little clearer by doing:
ev <- evaluate("stop(\"1\")\n2", stop_on_error = 2L)
Do you have any thoughts on how we might test this to make sure we don't accidentally break RMarkdown tracebacks again in the future? |
I tried a few things, but I am struggling to get a reproducible test for issue, let alone with evaluate only. It seems highly dependant on the context. So I am still unto this. |
@cderv I think it would be taking taking a suggests dependency on knitr, rmarkdown etc if we could get a good reprex for this. Have you tried callr + |
I was trying with
This is what I am trying, but with testthat using rlang and entracing by default error it seems, I can get something to reproduce the issue we have when using I think the issue is that with current evaluate logic before this PR, Even the trace cleaning problem is not an issue because it seems If we can use callr + rmarkdown or knitr, I'll try that. Initially, I tried to make a test in knitr instead directly (as this is knitr setting the logic of calling.handlers now) but it is not using testthat so I did not have snaphot available. |
`options(rlang_backtrace_on_error_report = "full")` is only useful when error is not thrown by render() and kept as cell output (e.g. error = TRUE)
…r = 2L behavior - Using evaluate only - In rmarkdown + knitr context
- Use knitr instead of rmarkdown - Test error thrown and capture in cell output
bc3e3d7
to
880b664
Compare
It seems something is different on CI than locally - looking into that. |
New change reduced the difference, but it seems to be related to some reproducibility on character used ❯ difft.exe .\stop-error-trace-trimmed.txt .\stop-error-trace-trimmed.new.txt
.\stop-error-trace-trimmed.new.txt --- Text
1 Error in `h()`: 1 Error in `h()`:
2 ! ! 2 ! !
3 Backtrace: 3 Backtrace:
4 ▆ 4 x
5 1. └─global f() 5 1. \-global f()
6 2. └─global g() 6 2. \-global g()
7 3. └─global h() 7 3. \-global h()
8 Execution halted 8 Execution halted I probably need to set some reproducibilty setting when passing to |
testthat::local_reproducible_output() needs to be called in the background Rscript process too
because g() was missing
if (is.null(getOption("rlang_trace_top_env"))) { | ||
# If not already set, indicate the top environment to trim traceback | ||
options(rlang_trace_top_env = envir) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hadley doing this in evaluate allows to get trimmed traceback in evaluate()
itself. This is related to comment at #232 (comment)
See the new snapshot file without any evaluate internals.
For full context, this will be done at knitr level and so it will apply for evaluate()
in knitr context.
However, I don't know of the impact on doing that directly in evaluate. evaluate()
is used also in other tools (like testthat) and I wonder if this could have impact.
Maybe @lionel- you have some advice on setting this here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My gut feeling is that it's worth it, but I don't know if there will be other negative effects.
After discussing with @lionel- , our conclusion was that
invokeRestart("error")
may not be necessary.When
stop_on_error = 2L
, the code needs to stop on error, which will happen if the handler called inwithCallingHandler()
returnsSo in this case, the handler could simply return NULL.
This solve the traceback problem encountered with latest evaluate and current rlang and knitr logic for entracing.
It also solve the traceback trimming problem that is created when
invokeRestart()
is used. With currentinvokeRestart("error", cnd)
, thesys.frames()
that is handled by the traceback is not containing the same environments it seems.Also calling
signalCondition(cnd)
in the restart handler was triggering some global handlers registered in Positron or in RStudio IDE - which led to differences in the context where rendering happened.Which this change,
rmarkdown::render()
shows a rlang traceback with only the cell's function in all context: Positron, RStudio IDE and R console.However, the snapshot test has changed, as output is now captured. I think it is ok though.
Regarding #231 and the idea of auto entracing, this was supposed to be done in knitr already. The change to
withRestart()
in recent evaluate demands an adaptation in knitr. I have a PR to come on knitr side to help with this.