问题
I have a function fun
that often produces warnings and occasionally throws errors. I am trying to use tryCatch
to log warnings and errors, as suggested in this answer. How can I simultaneously store the warnings and errors?
Here is a minimal setup:
# Function for warnings, errors.
fun <- function(i) {
# Print warnings as they come in.
options(warn = 1)
# Issue warning.
warning(paste("Warn.", i))
# Stop.
if(i == 3) { stop(paste("Err.", i)) }
# Restore warning default behaviour.
options(warn = 0)
}
Evaluating fun
with tryCatch
:
# Storage
warns = list()
errs = list()
# Try catch the function and log the warnings/ errors.
for (i in 1:4) {
tryCatch(fun(i),
warning = function(w) warns[[i]] <<- w,
error = function(e) errs[[i]] <<- e
)
}
However, the output shows that the error hasn't been stored.
warns
# [[1]]
# <simpleWarning in fun(i): Warn. 1>
#
# [[2]]
# <simpleWarning in fun(i): Warn. 2>
#
# [[3]]
# <simpleWarning in fun(i): Warn. 3>
#
# [[4]]
# <simpleWarning in fun(i): Warn. 4>
errs
# list()
回答1:
Based on Ronak's helpful comment and the following question How do I save warnings and errors as output from a function?, the code can be simplified as follows:
# Storage.
warns = list()
errs = list()
# Example function.
fun <- function(i) {
# Issue warning.
warning(paste("Warn.", i))
# Stop.
if(i == 3) { stop(paste("Err.", i)) }
}
# Evaluate `fun`.
for (i in 1:4) {
tryCatch(withCallingHandlers(
expr = fun(i),
# Handle the warnings.
warning = function(w) {
warns <<- c(warns, list(w))
invokeRestart("muffleWarning")
}),
# Handle the errors.
error = function(e) {
errs <<- c(errs, list(e))
}
)
}
The output then looks like:
warns
# [[1]]
# <simpleWarning in fun(i): Warn. 1>
#
# [[2]]
# <simpleWarning in fun(i): Warn. 2>
#
# [[3]]
# <simpleWarning in fun(i): Warn. 3>
#
# [[4]]
# <simpleWarning in fun(i): Warn. 4>
errs
# [[1]]
# <simpleError in fun(i): Err. 3>
More information and links are provided in the question linked above.
来源:https://stackoverflow.com/questions/57669971/how-to-correctly-log-warnings-and-errors-using-trycatch-in-r