R:在记录堆栈跟踪后捕获错误并继续执行(tryCatch 没有可用的回溯)

标签 r logging error-handling

我在服务器上运行的 R 中有许多无人值守的批处理作业,我必须在它们运行后分析作业失败。

我正在 try catch 错误以记录它们并从错误中优雅地恢复,但我无法获得堆栈跟踪 ( 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...
})

运行上面的代码会产生以下输出:

simpleError in f(): object 'variable.not.found' not found

No traceback available



回溯不可用,原因记录在 R 帮助 ( ?traceback ) 中:

Errors which are caught via try or tryCatch do not generate a traceback, so what is printed is the call sequence for the last uncaught error, and not necessarily for the last error.



换句话说:用 tryCatch 捕获错误确实会杀死堆栈跟踪!

我怎样才能
  • 处理错误
  • 记录堆栈跟踪(回溯)以供进一步检查
  • [可选] 不使用无法保证在 future 工作的未记录或隐藏的 R 内部函数?

  • 多谢!

    最佳答案

    抱歉回答太长,但我想在一个答案中总结所有知识和引用!

    需要解决的主要问题

  • tryCatch将调用堆栈“展开”到 tryCatch打电话让tracebacksys.calls不再包含完整的堆栈跟踪以识别导致错误或警告的源代码行。
  • tryCatch aborts the execution if you catch a warning通过为 warning 传递处理函数健康)状况。如果您只想记录警告,则无法正常继续执行。
  • dump.frames写入堆栈跟踪的评估环境(帧)以允许事后调试(= 检查每个函数调用中可见的变量值)但 dump.frames "forgets" to save the workspace too if you set the parameter to.file = TRUE .因此可能会丢失重要的对象。
  • 找到一个简单的日志框架,因为 R 不支持开箱即用的体面日志记录
  • 使用源代码行丰富堆栈跟踪。

  • 解决方案概念
  • 使用 withCallingHandlers而不是 tryCatch获取指向引发错误或警告的源代码行的完整堆栈跟踪。
  • 仅在 withCallingHandlers 内捕获警告(不在 tryCatch 中),因为它只调用处理函数但不改变程序流程。
  • 环绕withCallingHandlerstryCatch根据需要捕获和处理错误。
  • 使用 dump.frames使用参数 to.file = FALSE将转储写入名为 last.dump 的全局变量中并通过调用 save.image 将其与全局环境一起保存到文件中.
  • 使用日志框架,例如。 G。包裹futile.logger .
  • 当您设置 options(keep.source = TRUE) 时,R 会跟踪源代码引用.您可以将此选项添加到您的 .Rprofile文件或使用设置此选项的启动 R 脚本和 source那么你的实际 R 脚本。
  • 要使用跟踪的源代码行丰富堆栈跟踪,您可以使用未记录(但广泛使用)的函数 limitedLabels .
  • 要从堆栈跟踪中过滤掉 R 内部函数调用,您可以删除所有没有源代码行引用的调用。

  • 执行

    代码模板

    而不是使用 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替代品
  • 使用在 try catch 时执行多次尝试(重试)的功能记录警告和错误,例如。 G。访问不可靠的网络驱动器:

    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:在记录堆栈跟踪后捕获错误并继续执行(tryCatch 没有可用的回溯),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39964040/

    相关文章:

    php - 获取数组中的所有 PHP 错误

    r - 使用cowplot将x和y laxis标签添加到ggplot-grid构建

    elasticsearch - Fluentd-无法与Elasticsearch通信,无法重置连接并重试。 getaddrinfo:名称或服务未知(SocketError)

    r - 将数据表导出到 R 中的 Google Maps KML

    java - Lombok 分配自定义记录器变量名称

    c# - Asp.Net MVC 默认路由

    java - 如何获得在Axon错误处理程序中产生错误的事件处理程序?

    powershell - Powershell错误处理和记录

    java - 内存不足错误(Java): Java heap space

    RS-DBI 驱动程序警告 : (unrecognized MySQL field type 7 in column 1 imported as character)