如何获取最后一个错误

问题描述 投票:0回答:2

我可以使用

.Last.value

获取最后计算的值
2 + 2
## [1] 4
.Last.value
## [1] 4

我可以使用

last.warning
访问最新警告。

warning("!!!")
## Warning message:
## !!! 
last.warning
## $`!!!`
##  NULL

我可以使用

geterrmessage()

获取最新错误消息的文本
stop("!!!")
## Error: !!!
geterrmessage()
## [1] "Error: !!!\n"

如果我提前知道可能会抛出错误,我可以使用

tryCatch
返回错误对象。

tryCatch(stop("!!!"), error = identity)
## <simpleError in doTryCatch(return(expr), name, parentenv, handler): !!!>

抛出最后一个错误后,如何将其作为对象检索?

例如,如果我输入

stop("!!!")

然后我希望能够输入

getlasterror()
或类似内容并检索
simpleError
对象。

r error-handling
2个回答
2
投票

现代方式

如果您是代码的作者,解决此问题的现代方法是使用

rlang
包。您使用
abort()
抛出错误,然后使用
last_error()
检索最后一个错误。

library(rlang)
f <- function() {
  abort("@@@")
}
f()
## Error: @@@
last_error()
## <error>
## message: @@@
## class:   `rlang_error`
## backtrace:
##  ─base::withCallingHandlers(...)
##  ─global::f()
## Call `summary(rlang::last_error())` to see the full backtrace
g <- function() {
  msg <- "###"
  abort(msg)
}
g()
## Error: ###
last_error()
## <error>
## message: ###
## class:   `rlang_error`
## backtrace:
##  ─base::withCallingHandlers(...)
##  ─global::g()
## Call `summary(rlang::last_error())` to see the full backtrace
h <- function() {
  err_fn <- abort
  err_fn("$$$")
}
h()
## Error: $$$
last_error()
## <error>
## message: $$$
## class:   `rlang_error`
## backtrace:
##  ─base::withCallingHandlers(...)
##  ─global::h()
## Call `summary(rlang::last_error())` to see the full backtrace

其局限性在于它不适用于

stop()
生成的错误。


原答案

根据 David Arenburg 的评论,您可以将

tryCatch()
与回溯结合使用。

get_last_error <- function()
{
  tr <- .traceback()
  if(length(tr) == 0)
  {
    return(NULL)
  }
  tryCatch(eval(parse(text = tr[[1]])), error = identity)
}

示例:

# before an error is thrown
get_last_error()
## NULL

# after an error at the top level
stop("!!!")
## Error: !!!
get_last_error()
## <simpleError in eval(expr, envir, enclos): !!!>

# after an error inside a function
f <- function() stop("@@@")
f()
## Error in f() : @@@
get_last_error()
## <simpleError in eval(expr, envir, enclos): @@@>

限制:

当您重新评估错误代码时,所有变量都需要可用。所以下面的例子不起作用,例如:

g <- function()
{
  msg <- "###"
  stop(msg)
}

g()
## Error in g() : ###
get_last_error()
## <simpleError in stop(msg): object 'msg' not found>

h <- function()
{
  err_fn <- stop
  err_fn("$$$")
}

h()
## Error in h() : $$$
get_last_error()
## <simpleError in eval(expr, envir, enclos): could not find function "err_fn">

通过设置

options(error = dump.frames)
,发生错误时的调用堆栈将存储在全局环境中名为
last.dump
的变量中。环境
last.dump[length(last.dump)]
有时包含错误对象,有时包含会创建错误的参数。

debugger(last.dump)
允许对堆栈进行交互式事后探索,作为错误对象的替代方法。


0
投票

我可以使用 rlang::last_error() 来做到这一点,但之前有必要运行 rlang::global_entrace() 。这可确保所有错误都保存到回溯中。

© www.soinside.com 2019 - 2024. All rights reserved.