-
Notifications
You must be signed in to change notification settings - Fork 323
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
Adding wrap
Parameter to test_dir
, test_check
, and run_tests
#586
Comments
Thanks. A straightforward fix would be to expose the |
I'd rather leave this for now, and think more about the handler support in rlang. |
@hadley note that 37cc0d0 breaks existing use cases and without adding the |
This seems ok to me - library(testthat)
f <- tempfile()
cat(
"
withCallingHandlers(
stop('This should be handled'),
error=function(e) cat('handled\n')
)
test_that('truth', {expect_true(TRUE)})
",
file=f
)
test_file(f) # fails
#> handled
#> 1
#> Failed -------------------------------------------------------------------------------------------------------------------
#> 1. Error: (unknown) (@file11e33799dbdb7#2) -------------------------------------------------------------------------------
#> This should be handled
#> 1: withCallingHandlers(stop("This should be handled"), error = function(e) cat("handled\n")) at /tmp/RtmpoLCXK7/file11e33799dbdb7:2
#> 2: stop("This should be handled")
#>
#> DONE =====================================================================================================================
#> Don't worry, you'll get it.
test_file(f, wrap=FALSE) # works
#> handled
#> Error in withCallingHandlers(stop("This should be handled"), error = function(e) cat("handled\n")): This should be handled
#>
#> DONE ===================================================================================================================== |
If that's not correct, it would be useful for you to write up what you do expect, and why. |
I'm sorry I was not very clear about the exact nature of the problem:
To try to clarify a little, I run with the check reporter:
Notice how in the second run the tests are not considered to fail. The problem is that with I explore the This matters to me because I built the tests for my own unit testing framework with |
The It seems the best solution would be to put your code within |
Thanks @lionel, I'll explore the use of |
It's just that the |
Note that I'm NOT looking for an error to be re-thrown, in fact, I'm looking for the exact opposite. I want
A stand alone Previously I could just run some code that used |
Yes sorry I got confused. If we rethrow errors from the tryCatch the stack is of course unwound.
I don't think it's flawed, it's just that it doesn't make sense to mark an exceptional condition (an error) as handled if the code that threw the error is not designed for this kind of recovery (i.e. it doesn't set a restart point). |
But what about warnings? In my use case I'm evaluating arbitrary code inside Keep in mind I'm evaluating arbitrary code. I don't know if it will contain warnings or not, e.g.:
Where exp is supplied by the user. |
All warnings have restart points, which makes sense because they are not exceptional conditions. So you can invoke the muffleWarning restart from your handler to mark it as handled. Your local handler will be the last one called by R. |
Unfortunately |
Note that if you were able to mark errors as handled with a local handler, all kinds of undefined behaviours would arise because you'd be continuing code from errors issued anywhere, not just those issued at top level. |
My understanding of R semantics are that code should be allowed to continue after a condition is signaled. I.e. signaling a condition is not an interrupt per se. The interrupt can be optionally raised by that code after signaling the condition. As such, I want to be able to handle all conditions and let code interrupt only if it actually tries to interrupt. For example, in:
I capture and record all conditions in my handling code, but because I use
In other words: code should continue to evaluate after a condition is signaled, unless an interrupt is also raised as that is the default R behavior. This contrast to only resuming code if it sets a restart point. As you note PS: Thanks for your time and patience in discussing this with me. |
But standard semantics of R and Common Lisp also imply that all conditions are catchable. Maybe what you're after is the ability to register handlers that have precedence over handlers added later in the call stack. |
IIUC, rethrowing fatal errors as suggested earlier would solve your problems? |
Only unhandled ones though. If a condition is handled by an inner handler it shouldn't have to be caught by an outer unless it is re-thrown. Compare:
Basically |
|
I think what you're missing is that merely running a handler doesn't mean that the condition is handled. It is only handled if control flow jumps out of the handler, e.g. by a non-local return or a restart invocation.
Only fatal error are caught so IIUC you wouldn't want code to resume. |
I need to mimic what happens when code is run on the command line, without handlers, which is:
Additionally, I need to record the condition that was signaled. You can do this with How would you solve this problem (let code continue to evaluate after a |
Again, this only happens for fatal conditions which would stop the As for recording the fatal errors, this would be solved because rethrowing them would give a chance to run your handlers. However the call stack at time of handling will be different and that might be an issue. If that is an issue it might make sense to add the original call stack in the condition data. |
Maybe I'm not understanding what you are saying. Let's try one more example. We have function
And we want to record the values of the condition issued, in addition to the return value. Compare:
to:
There are no fatal conditions involved here. In the first case I can recover the condition and the result because the |
In your example you're catching all conditions whereas testthat only catches Anyway, we're losing too much time discussing this. Apparently all we need is the ability for other packages to load the test files with all testthat infrastructural features (file handling, reporter invocation), and a |
Great, thanks for your patience with me. FWIW the related PR is: #597. Hopefully I can get your suggestion of |
Ok, I'm convinced. |
@krlmlr, Since 37cc0d0 it is no longer possible to run code with
test_dir
that involveswithCallingHandlers
error handling. This is because the default source action now setswrap=TRUE
, which causes all sourced code to be run withintest_code
.Since
wrap
is not exposed intest_dir
there is no way to disable this behavior when usingtest_dir
(ortest_check
).A simple example of the problem (here we just use
test_file
sincetest_file
has the argument so we can show both cases):For reference, more details on the running
withCallingHandlers
insidetry
block issue.I'm happy to submit a PR that addresses this if you'd like.
The text was updated successfully, but these errors were encountered: