我在服务器上运行的R中有许多无人值守的批处理作业,运行后我必须分析作业失败。
我试图捕获错误以将其记录并从错误中恢复,但是我无法获取堆栈跟踪(traceback
)来记录导致错误的R命令的代码文件名和行号。 (愚蠢的)可复制示例:
f <- function() {
1 + variable.not.found # stupid error
}
tryCatch( f(), error=function(e) {
# Here I would log the error message and stack trace (traceback)
print(e) # error message is no problem
traceback() # stack trace does NOT work
# Here I would handle the error and recover...
})
运行上面的代码将产生以下输出:
跟踪不可用,其原因已在R帮助(
?traceback
)中记录:换句话说:使用
tryCatch
捕获错误确实会杀死堆栈跟踪!我怎么能够
多谢!
最佳答案
很抱歉,回答很长,但我想在一个答案中总结所有知识和引用!
要解决的主要问题
tryCatch
将调用堆栈“展开”到tryCatch
调用,以便traceback
和sys.calls
不再包含完整的堆栈跟踪,以标识导致错误或警告的源代码行。 tryCatch
条件的处理程序函数warning
aborts the execution if you catch a warning。如果只想记录警告,则无法照常继续执行。 dump.frames
写入堆栈跟踪的评估环境(框架),以允许事后调试(=检查每个函数调用中可见的变量值),但是 dump.frames
"forgets" to save the workspace too if you set the parameter to.file = TRUE
。因此,重要的对象可能会丢失。 解决方案概念
withCallingHandlers
而不是tryCatch
获取指向引发错误或警告的源代码行的完整堆栈跟踪。 withCallingHandlers
(而不是tryCatch
)内捕获警告,因为它仅调用处理程序函数,但不会更改程序流。 withCallingHandlers
包围tryCatch
,以根据需要捕获和处理错误。 dump.frames
与参数to.file = FALSE
一起使用,将转储写入名为last.dump
的全局变量中,并通过调用save.image
将其与全局环境一起保存到文件中。 futile.logger
。 options(keep.source = TRUE)
时,.Rprofile
文件中,也可以使用设置该选项的启动R脚本,然后使用source
您的实际R脚本。 limitedLabels
函数。 实作
代码模板
代替使用
tryCatch
,您应该使用以下代码片段:library(futile.logger)
tryCatch(
withCallingHandlers(<expression>,
error = function(e) {
call.stack <- sys.calls() # is like a traceback within "withCallingHandlers"
dump.frames()
save.image(file = "last.dump.rda")
flog.error(paste(e$message, limitedLabels(call.stack), sep = "\n"))
}
warning = <similar to error above>
}
error = <catch errors and recover as you would do it normally>
# warning = <...> # never do this here since it stops the normal execution like an error!
finally = <your clean-up code goes here>
}
通过包(
tryCatchLog
)可重用的实现我已经用上述所有概念实现了一个简单的程序包。
它使用
tryCatchLog
包提供功能futile.logger
。用法:
library(tryCatchLog) # or source("R/tryCatchLog.R")
tryCatchLog(<expression>,
error = function(e) {
<your error handler>
})
您可以在github上找到免费的源代码:
https://github.com/aryoda/tryCatchLog
您也可以
source
tryCatchLog
function,而不使用完整的软件包。示例(演示)
请参阅demo file,其中提供了很多注释以解释其工作方式。
引用文献
其他
tryCatch
替换Handling errors before warnings in tryCatch
withJavaLogging
函数不依赖于其他软件包,该函数还使用limitedLabels
丰富了对调用堆栈的源代码引用:Printing stack trace and continuing after error occurs in R
其他有用的链接
http://adv-r.had.co.nz/Exceptions-Debugging.html
A Warning About warning() - avoid R's warning feature
In R, why does withCallingHandlers still stops execution?
How to continue function when error is thrown in withCallingHandlers in R
Can you make R print more detailed error messages?
How can I access the name of the function generating an error or warning?
How do I save warnings and errors as output from a function?
options(error=dump.frames) vs. options(error=utils::recover)
General suggestions for debugging in R
Suppress warnings using tryCatch in R
R Logging display name of the script
Background information about the "srcrefs" attribute (Duncan Murdoch)
get stack trace on tryCatch'ed error in R
关于r - R : Catch errors and continue execution after logging the stacktrace (no traceback available with tryCatch),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62900655/