在tryCatch中处理警告之前的错误 [英] Handling errors before warnings in tryCatch

查看:140
本文介绍了在tryCatch中处理警告之前的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一个抛出错误和警告的功能。
(相关:关于警告的警告



通常,警告将会出现错误。在这种情况下,我想忽略警告并只处理错误。



另一方面,如果只有一个警告(没有错误),那么我想抓住警告。



我正尝试使用恶作剧的易于使用的 tryCatch



我的直接问题是:
有没有办法强制执行 tryCatch 来处理<$ c $ s s s(或者在出现错误时忽略警告)?



我从?tryCatch 文档中的理解是条件处理FIFO,在这种情况下,我直接问题的答案是否定的 - 至少不是直接的。在这种情况下,是否可以处理警告,然后继续捕获错误?



解决方案不适用于我:




  • suppressWarnings #我还想抓住并处理警告

  • options(warn = 2)#某些警告是无害的




 相关的`?tryCatch` 

如果在评估expr时发出条件信号,那么从最近建立的处理程序开始检查建立的处理程序,以便匹配条件类别。当在单个tryCatch中提供几个处理程序时,第一个处理程序被认为比第二个更近。如果找到一个处理程序,那么控件就被传递到建立处理程序的tryCatch调用,找到的处理程序和所有更新的处理程序都被解除了,处理程序以条件为参数被调用,处理程序返回的结果返回为




下面是一个玩具示例:



  F.errorAndWarning<  -  function(){
warning(Warning before the error)
cat(我已经移动了)
stop(error)
TRUE
}
F.error< - function(){stop(error); ()


测试< - 函数(F)
tryCatch(expr = {F}()
,error = function CAUGHT)
,warning = function(w)cat(WARNING CAUGHT)


test(F.error)
#ERROR CAUGHT
测试(F.errorAndWarning)
#警告CAUGHT

预期/理想输出:

  test(F.errorAndWarning)
#ERROR CAUGHT


解决方案

这涉及到是否可以处理警告,功能继续而仍然捕捉到错误?



我有一个类似的问题,我想绑定我的日志功能的警告和错误到try catch并且始终在警告之后继续,并且也可以在尝试捕获时执行多次尝试,例如用于访问脆弱的网络驱动器。这是我最后使用的。这个或一个更简化的版本可以帮助你的后期。

  MyLibrary.Sys.Try<  -  function(
expr,#将通过调用Try
评估的表达式errorMessage =,#可选的前缀字符串添加到错误输出
warningMessage =,#可选的前缀字符串添加到警告输出
failureMessage =,#可选的前缀字符串添加到失败的所有尝试
finally = NULL,#在tryCatch结束时执行的可选表达式
attempts = 1,#尝试次数尝试评估表达式
suppressError = TRUE,#如果所有尝试失败,调用只是记录错误或提高错误
quiet = FALSE#正常返回表达式或不可见
){
tryNumber< - 0
while(tryNumber< attempts){
tryNumber< - tryNumber + 1

#如果不压制e错误,这是最后一个
#尝试,然后直接评估表达式
if(tryNumber == attempts&&& !suppressError){
#注意:当
#以非交互模式运行时,我认为有些警告可能会丢失。但是我认为这应该是可以的
#,因为即使是嵌套调度似乎接受了他们:
#MyLibrary.Sys.Try(MyLibrary.Sys.Try(function(),suppressError = F))
return(expr)
}

tryCatch({
#将警告处理程序设置为空函数
#,因此不会由tryCatch引发,将
#执行byCallingHandlers
options(warning.expression = quote(function(){}))
withCallingHandlers({
if(quiet){
return (invisible(expr))
} else {
return(expr)
}
},error = function(ex){
MyLibrary.Sys.Log.Error (errorMessage,ex)
},warning = function(warn){
#在这里发出的相同警告消息是
#的问题,以避免只记录它在给定分钟内发生的第一个
#时间。
warnStamp< - paste(Sys.time(),warn,collapse =_,sep =)
if(!same(warnStamp,getOption(MyLibrary.LAST.WARNING )){
if(!(interactive()&& is.null(getOption(warning.expression)))){
MyLibrary.Sys.Log.Warning(warningMessage,warn)
}
选项(MyLibrary.LAST.WARNING = warnStamp)
}
})
},error = function(ex){
#因为它已经被上面的处理程序记录
#的错误。需要被压制
#才能直接调用停止,因为上面的
#处理程序通过它。
},finally = {
#将警告处理程序设置为默认值
#的NULL,这将导致它恢复为
#正常行为。如果一个自定义处理程序通常是
#,那么将它存储在
#之上是有意义的,然后在这里恢复。但是现在不需要
options(warning.expression = NULL)
if(!is.null(finally)){
if(quiet){
return(invisible (最后))
} else {
return(finally)
}
}
})
}

msg< ; - 粘贴(ifelse(nchar(failureMessage)> 0, - ,),无法调用表达式,尝试尝试,sep =)
MyLibrary。 Sys.Log.Error(failureMessage,msg)
}


I am dealing with a function that is throwing both errors and warnings. (related: A Warning About Warning )

Often, a warning will proceed an error. In these situations, I would like to disregard the warning and process only the error.

On the other hand, if there is only a warning (with no error), then I would like to catch the warning.

I am attempting to work with the notoriously-easy-to-use tryCatch.

My immediate question is: Is there a way to force tryCatch to process errors before warnings (or to disregard warnings when there is an error)?

My understanding from the ?tryCatch documentation is that conditions are handled FIFO, in which case the answer to my immediate question is No - at least not directly. In which case, is it possible to process the warning and then have the function continue while still catching errors?

solutions NOT available to me:

  • suppressWarnings # I would like to still catch and handle the warnings
  • options(warn=2) # certain warnings are harmless

     relevant from `?tryCatch`

If a condition is signaled while evaluating expr then established handlers are checked, starting with the most recently established ones, for one matching the class of the condition. When several handlers are supplied in a single tryCatch then the first one is considered more recent than the second. If a handler is found then control is transferred to the tryCatch call that established the handler, the handler found and all more recent handlers are disestablished, the handler is called with the condition as its argument, and the result returned by the handler is returned as the value of the tryCatch call.

Below is a toy example:

F.errorAndWarning <- function() {
    warning("Warning before the error")
    cat("I have moved on.")
    stop("error")
    TRUE
}
F.error <- function() {stop("error"); TRUE}


test <- function(F)
  tryCatch(expr= {F}()
          , error=function(e)   cat("ERROR CAUGHT")
          , warning=function(w) cat("WARNING CAUGHT")
          )

test(F.error)
# ERROR CAUGHT
test(F.errorAndWarning)
# WARNING CAUGHT

Expected / ideal output:

test(F.errorAndWarning)
# ERROR CAUGHT

解决方案

This relates to the "is it possible to process the warning and then have the function continue while still catching errors?" question.

I had a similar issue where I wanted to bind my logging functions for warnings and errors to the try catch and always continue after warnings and also be able to perform multiple attempts at try catch, e.g. for accessing a flimsy network drive. This is what I ended up using. This or a more simplified version could help with what your after.

MyLibrary.Sys.Try <- function(
    expr,                   # Expression that will be evaluated by the call to Try
    errorMessage="",        # Optional prepended string to add to error output
    warningMessage="",      # Optional prepended string to add to warning output
    failureMessage="",      # Optional prepended string to add to failing all attempts
    finally=NULL,           # Optional expression to be executed at the end of tryCatch
    attempts=1,             # Number of attempts to try evaluating the expression
    suppressError=TRUE,     # Should the call just log the error or raise it if all attempts fail
    quiet=FALSE             # Return expression normally or as invisible
) {
    tryNumber <- 0
    while(tryNumber<attempts) {
        tryNumber <- tryNumber + 1

        # If not suppressing the error and this is the last
        # attempt then just evaluate the expression straight out
        if(tryNumber == attempts && !suppressError){
            # NOTE: I think some warnings might be lost here when
            # running in non-interactive mode. But I think it should be okay
            # because even nested dispatch seems to pick them up:
            # MyLibrary.Sys.Try(MyLibrary.Sys.Try(function(),suppressError=F))
            return(expr)
        }

        tryCatch({
            # Set the warning handler to an empty function
            # so it won't be raised by tryCatch but will
            # be executed by withCallingHandlers
            options(warning.expression=quote(function(){}))
            withCallingHandlers({
                if(quiet) {
                    return(invisible(expr))
                } else {
                    return(expr)
                }
            },error=function(ex){
                MyLibrary.Sys.Log.Error(errorMessage,ex)
            }, warning=function(warn){
                # Had issues with identical warning messages being
                # issued here so to avoid that only log it the first
                # time it happens in a given minute. 
                warnStamp <- paste(Sys.time(),warn,collapse="_",sep="")
                if(!identical(warnStamp,getOption("MyLibrary.LAST.WARNING"))) {
                    if(!(interactive() && is.null(getOption("warning.expression")))){
                        MyLibrary.Sys.Log.Warning(warningMessage,warn)
                    }
                    options(MyLibrary.LAST.WARNING=warnStamp)
                }
            })
        },error=function(ex){
            # Suppressing the error since it's been logged
            # by the handler above. Needs to be suppressed
            # to not invoke the stop directly since the
            # handler above passes it through.
        },finally={
            # Set the warning handler to the default value
            # of NULL which will cause it to revert to it's
            # normal behaviour. If a custom handler is normally
            # attached it would make sense to store it above
            # and then restore it here. But don't need that now
            options(warning.expression=NULL)
            if(!is.null(finally)){
                if(quiet) {
                    return(invisible(finally))
                } else {
                    return(finally)
                }
            }
        })
    }

    msg <- paste(ifelse(nchar(failureMessage)>0," - ",""),"Failed to call expression after ",attempts," attempt(s)",sep="")
    MyLibrary.Sys.Log.Error(failureMessage,msg)
}

这篇关于在tryCatch中处理警告之前的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆