How do I save warnings and errors as output from a function? How do I save warnings and errors as output from a function? r r

How do I save warnings and errors as output from a function?


Maybe this is the same as your solution, but I wrote a factory to convert plain old functions into functions that capture their values, errors, and warnings, so I can

test <- function(i)    switch(i, "1"=stop("oops"), "2"={ warning("hmm"); i }, i)res <- lapply(1:3, factory(test))

with each element of the result containing the value, error, and / or warnings. This would work with user functions, system functions, or anonymous functions (factory(function(i) ...)). Here's the factory

factory <- function(fun)    function(...) {        warn <- err <- NULL        res <- withCallingHandlers(            tryCatch(fun(...), error=function(e) {                err <<- conditionMessage(e)                NULL            }), warning=function(w) {                warn <<- append(warn, conditionMessage(w))                invokeRestart("muffleWarning")            })        list(res, warn=warn, err=err)    }

and some helpers for dealing with the result list

.has <- function(x, what)    !sapply(lapply(x, "[[", what), is.null)hasWarning <- function(x) .has(x, "warn")hasError <- function(x) .has(x, "err")isClean <- function(x) !(hasError(x) | hasWarning(x))value <- function(x) sapply(x, "[[", 1)cleanv <- function(x) sapply(x[isClean(x)], "[[", 1)


Try the evaluate package.

library(evaluate)test <- function(i)    switch(i, "1"=stop("oops"), "2"={ warning("hmm"); i }, i)t1 <- evaluate("test(1)")t2 <- evaluate("test(2)")t3 <- evaluate("test(3)")

It currently lacks a nice way of evaluating expression though - this is mainly because it's targetted towards reproducing exactly what R output's given text input at the console.

replay(t1)replay(t2)replay(t3)

It also captures messages, output to the console, and ensures that everything is correctly interleaved in the order in which it occurred.


I have merged Martins soulution (https://stackoverflow.com/a/4952908/2161065) and the one from the R-help mailing list you get with demo(error.catching).

The main idea is to keep both, the warning/error message as well as the command triggering this problem.

myTryCatch <- function(expr) {  warn <- err <- NULL  value <- withCallingHandlers(    tryCatch(expr, error=function(e) {      err <<- e      NULL    }), warning=function(w) {      warn <<- w      invokeRestart("muffleWarning")    })  list(value=value, warning=warn, error=err)}

Examples:

myTryCatch(log(1))myTryCatch(log(-1))myTryCatch(log("a"))

Output:

> myTryCatch(log(1))

$value [1] 0 $warning NULL $error NULL

> myTryCatch(log(-1))

$value [1] NaN $warning $error NULL

> myTryCatch(log("a"))

$value NULL $warning NULL $error