Is there a way to get the warning
parameter of a tryCatch
to passthrough the result of the expr
even if there is a handled warning?
r <- tryCatch(
{
warning("I'm a warning!")
return(100) # I want the return value of the tryCatch to be this!
},
warning = function(w) {
# send a notification with the warning message
}
)
The result of r
should 100!
CodePudding user response:
tryCatch
doesn’t do this: each handler interrupts the expression’s execution and immediately returns to the caller.
Instead, this is a task for withCallingHandlers
, which handles a condition and then returns control back to the expression.
Here’s an example:
f = function () {
warnings = list()
self = environment()
r = withCallingHandlers({
warning("I'm a warning!")
100
},
warning = function (w) {
self$warnings = c(self$warnings, conditionMessage(w))
invokeRestart('muffleWarning')
}
)
list(r = r, warnings = warnings)
}
When we run it, this is the result:
f()
# $r
# [1] 100
#
# $warnings
# $warnings[[1]]
# [1] "I'm a warning!"
Note that you cannot use return()
here. It’s usually redundant anyway but in this particular context it would abort the execution of f
, so r
would never get assigned a value, and the rest of the function wouldn’t be executed.
Incidentally, invokeRestart('muffleWarning')
isn’t necessary; it suppresses the default handler which would print the warning to the standard error stream; you can remove it, and the call will work the same way, but the warning will additionally be printed. You can install your own restarts via withRestarts
.
The condition system in R is incredibly powerful but also quite complex, and the documentation is unfortunately essentially nonexistent. The best resource I know is the Conditions chapter in Advanced R, as well as an essay adapted from Lisp, Beyond Exception Handling: Conditions and Restarts, which is (IMHO) less approachable but explains the concepts more fundamentally.