假设您有一个使用TryCatch的函数f:
f <- function() {
tryCatch(stop('Argh'), error = function(x) {
message('f() error handler')
warning(x)
})
message('computing')
"Very Important Result"
}
>res <- f()
# f() error handler
# computing
# Warning message:
# In doTryCatch(return(expr), name, parentenv, handler) : Argh
>identical(res, "Very Important Result")
# [1] TRUE
到目前为止一切顺利。
但现在:
tryCatch(x <- f(), error = function(x) {
message('OUTER error handler !!!')
})
# f() error handler
# OUTER error handler !!!
> x
Error: object 'x' not found
在这种情况下,计算从未达到表达式 f中的消息('计算') 问题:这是预期的吗?
答案 0 :(得分:1)
try()
是使用tryCatch()
实现的,因此单凭这不能成为预期无法正常工作的原因。
try
#> function (expr, silent = FALSE)
#> {
#> tryCatch(expr, error = function(e) {
#> call <- conditionCall(e)
#> if (!is.null(call)) {
#> if (identical(call[[1L]], quote(doTryCatch)))
#> call <- sys.call(-4L)
#> dcall <- deparse(call)[1L]
#> prefix <- paste("Error in", dcall, ": ")
#> LONG <- 75L
#> msg <- conditionMessage(e)
#> sm <- strsplit(msg, "\n")[[1L]]
#> w <- 14L + nchar(dcall, type = "w") + nchar(sm[1L],
#> type = "w")
#> if (is.na(w))
#> w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L],
#> type = "b")
#> if (w > LONG)
#> prefix <- paste0(prefix, "\n ")
#> }
#> else prefix <- "Error : "
#> msg <- paste0(prefix, conditionMessage(e), "\n")
#> .Internal(seterrmessage(msg[1L]))
#> if (!silent && identical(getOption("show.error.messages"),
#> TRUE)) {
#> cat(msg, file = stderr())
#> .Internal(printDeferredWarnings())
#> }
#> invisible(structure(msg, class = "try-error", condition = e))
#> })
#> }
#> <bytecode: 0xa4a390>
#> <environment: namespace:base>
原来问题不在于嵌套tryCatch()
,而在于warning(x)
。后者抛出一个错误(由'外部'tryCatch()
捕获)。相应地更改示例会给我们预期的结果。
f <- function() {
tryCatch(stop('Argh'), error = function(w) {
message('f() error handler')
warning(w$message)
})
message('computing')
"Very Important Result"
}
tryCatch(x <- f(), error = function(e) str(e))
#> f() error handler
#> Warning in value[[3L]](cond): Argh
#> computing
x
#> [1] "Very Important Result"