I need to convert a warning to an error to be able to handle it further upstream (warnings are swallowed somewhere in the middle, over which I have no control; errors are not). To do this, I’m doing the following:
warning_to_error = function (expr)
withCallingHandlers(expr, warning = stop)
This works great:
> warning_to_error(warning('foobar'))
Error in withCallingHandlers(expr, warning = stop) : foobar
Unfortunately, this makes the error completely uncatchable:
> try(warning_to_error(warning('foobar')))
Error in withCallingHandlers(expr, warning = stop) : foobar
In my real situation, there are several layers between my warning_to_error
and the try
(including the logic that muffles warnings). How can I make the error raised by my calling handler catchable? Unfortunately I cannot use restarts as described in another Stack Overflow question because stop
doesn’t define a restart, and I once again have no control over the code doing the catching anyway.
This should tell you what is happening with your definition of warning_to_error
:
> tryCatch(warning_to_error(warning('foobar')), condition = print)
<simpleWarning in withCallingHandlers(expr, warning = stop): foobar>```
As the documentation for stop
says, when you call stop
with a condition, that condition is signalled to look for handlers, which means warning
handlers in this case. If you want an error handler to be invoked you need to signal an error condition. That is what happens when you set options(warn = 2)
for example. So you need something like
warning_to_error1 <- function (expr)
withCallingHandlers(expr,
warning = function(w)
stop("(converted from warning) ",
conditionMessage(w)))
That gives you
> tryCatch(warning_to_error1(warning('foobar')),
+ error = function(e) print("Got it"))
[1] "Got it"
Ideally we should provide a condition class and constructor for warnings converted to errors and use that internally for warn = 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With