R中的异常处理和堆栈展开

时间:2022-10-24 19:34:30

In order to set up a coherent exception handling interface for my colleagues' and my R scripts, I would like to employ the following tryCatch structure.

为了为我的同事和我的R脚本建立一个连贯的异常处理接口,我想使用以下tryCatch结构。

  1. An outer tryCatch is wrapped around a given R script. It is used to catch and handle fatal errors that require the script to abort.
  2. 外部tryCatch包含在给定的R脚本周围。它用于捕获和处理需要脚本中止的致命错误。
  3. User-specific tryCatch commands within the user's scripts. These should catch and, possibly, handle
    • 2a. non-fatal errors, where no script abortion is necessary
    • 2A。非致命错误,不需要脚本流产
    • 2b. fatal-errors that require the script to abort. The error is handled by the outer tryCatch [see 1.]
    • 2B。致命错误,需要脚本中止。该错误由外部tryCatch处理[见1.]
    • 2c. fatal-errors with additional error information. Error handled by outer tryCatch.
    • 2C。带有其他错误信息的致命错误。外部tryCatch处理错误。
  4. 用户脚本中特定于用户的tryCatch命令。这些应该捕获并且可能处理2a。非致命错误,不需要脚本流产2b。致命错误,需要脚本中止。该错误由外部tryCatch处理[见1.] 2c。带有其他错误信息的致命错误。外部tryCatch处理错误。

The following code is how I would implement these features. However, since I am not an expert in R, I would like to ask whether this is a good approach. Specifically:

以下代码是我如何实现这些功能。但是,由于我不是R的专家,我想问一下这是否是一个好方法。特别:

Q1. Is it ok not to specify an error handler in the inner tryCatch and to wait for the outer tryCatch to handle that error (see 2b. above and code below)?

Q1。可以不在内部tryCatch中指定错误处理程序并等待外部tryCatch处理该错误(参见上面的2b。以及下面的代码)?

Q2. Is rethrowing the same error (see 2c. above/below) within a handler correct/considered good coding style?

Q2。是否在处理程序中重新抛出相同的错误(参见上面/下面的2c)正确/认为良好的编码风格?

Thank you!

谢谢!

#outer tryCatch, see 1.
tryCatch({
  #user code block
  #2a. user specific tryCatch, object "vec" not defined
  tryCatch(print(vec),error=function(e) {print("Non-fatal error. Script execution continued.");print(e);})

  #2b. user specific tryCatch
  tryCatch(vec*2)

  #2c. user specific tryCatch
  tryCatch(vec*parameter1, error=function(e) {print("Additional fatal error information. Script execution aborted.");stop(e);})
  #end of user code block
},
     #outer tryCatch error handler in order to handle fatal errors
     error=function(e) {print("Fatal error");print(e);} 
    )

1 个解决方案

#1


5  

It's perfectly fine to catch only some errors, leaving other for the outer handler or no handler at all. The error system is quite a bit more flexible than typically used, so for re-throwing an error you might think of creating your own error type

只捕获一些错误,将其他错误留给外部处理程序或根本没有处理程序,这是完全正常的。错误系统比通常使用的更灵活,因此对于重新抛出错误,您可能会考虑创建自己的错误类型

ourError <-
    function(original, message, class="ourError")
{
    msg <- paste(message, conditionMessage(original), sep="\n  ")
    structure(list(message = msg, call = conditionCall(original)),
              class = c(class, class(original)))
}

and throwing and / or handling that

投掷和/或处理

tryCatch(vec*parameter1, error=function(e) {
    err <- ourError(e, "addition fatal info; script aborted")
    stop(err)
})

One advantage of this is that additional behaviors can be specified in the top-level handler, using the class returned by ourError()

这样做的一个优点是可以使用ourError()返回的类在*处理程序中指定其他行为。

tryCatch({
    tryCatch(stop("oops"), error=function(e) {
        err <- ourError(e, "addition fatal info; script aborted",
                      c("fatal", "ourError"))
        stop(err)
    })
}, ourError=function(err) {
    message("We caught but didn't handle this:\n", err)
}, error =function(err) {
    message("This one got away: ", err)
})

#1


5  

It's perfectly fine to catch only some errors, leaving other for the outer handler or no handler at all. The error system is quite a bit more flexible than typically used, so for re-throwing an error you might think of creating your own error type

只捕获一些错误,将其他错误留给外部处理程序或根本没有处理程序,这是完全正常的。错误系统比通常使用的更灵活,因此对于重新抛出错误,您可能会考虑创建自己的错误类型

ourError <-
    function(original, message, class="ourError")
{
    msg <- paste(message, conditionMessage(original), sep="\n  ")
    structure(list(message = msg, call = conditionCall(original)),
              class = c(class, class(original)))
}

and throwing and / or handling that

投掷和/或处理

tryCatch(vec*parameter1, error=function(e) {
    err <- ourError(e, "addition fatal info; script aborted")
    stop(err)
})

One advantage of this is that additional behaviors can be specified in the top-level handler, using the class returned by ourError()

这样做的一个优点是可以使用ourError()返回的类在*处理程序中指定其他行为。

tryCatch({
    tryCatch(stop("oops"), error=function(e) {
        err <- ourError(e, "addition fatal info; script aborted",
                      c("fatal", "ourError"))
        stop(err)
    })
}, ourError=function(err) {
    message("We caught but didn't handle this:\n", err)
}, error =function(err) {
    message("This one got away: ", err)
})