Capture Arbitrary Conditions with `withCallingHandlers`

后端 未结 4 1382
梦毁少年i
梦毁少年i 2020-12-31 18:05

The Problem

I\'m trying to write a function that will evaluate code and store the results, including any possible conditions signaled in the code. I\'ve got this

4条回答
  •  一向
    一向 (楼主)
    2020-12-31 18:40

    I think what you're looking for is to use withRestarts when your special condition is signaled, like from warning:

        withRestarts({
            .Internal(.signalCondition(cond, message, call))
            .Internal(.dfltWarn(message, call))
        }, muffleWarning = function() NULL)
    

    so

    evalcapt <- function(expr) {
      conds <- list()
      withCallingHandlers(
        val <- eval(expr),
        custom=function(e) {
          message("Caught condition of class ", deparse(class(e)))
          conds <<- c(conds, list(e))
          invokeRestart("muffleCustom")
      } )
      list(val=val, conditions=conds)
    }
    
    expr <- expression(withRestarts({
        signalCondition(myCondition)
    }, muffleCustom=function() NULL), 25)
    

    leads to

    > tryCatch(evalcapt(expr))   
    Caught condition of class c("custom", "simpleCondition", "condition")
    $val
    [1] 25
    
    $conditions
    $conditions[[1]]
    
    
    
    > tryCatch(
    +   evalcapt(expr),               
    +   custom=function(e) stop("Hijacked `evalcapt`!")  
    + )
    Caught condition of class c("custom", "simpleCondition", "condition")
    $val
    [1] 25
    
    $conditions
    $conditions[[1]]
    
    

提交回复
热议问题