Context
As Willem van Leesburg noted, it is not possible to use the traceback() function to display where an error occurred with tryCatch() , and as far as I know, there is currently no practical way to save the error position with basic functions in R when using tryCatch .
The idea of ββa separate error handler
The possible solution that I found consists of two parts, the main one of which is to write an error handler, similar to the Chrispy method , from "tracing the print stack and continuing after an error in R" , which creates a log with the error position. The second part writes this output to a variable, similar to what was suggested by Ben Bolker in "Is it possible to redirect console output to a variable" .
The call column in R seems to be cleared when an error occurs, and then processed (maybe I'm wrong, so any information is welcome), so we need to fix the error during its occurrence.
Script with an error
I used an example from one of your previous questions regarding where the error is R , with the following function stored in a file called "TestError.R", which I call in my example below:
# TestError.R f2 <- function(x) { if (is.null(x)) "x is Null" if (x==1) "foo" } f <- function(x) { f2(x) }
Bug tracking function
This is a feature that I adapted for Chrispy code, as I mentioned above. After execution, if an error occurs, the code below will print where the error occurred, in the case of the above function, it will print: "Error occuring: Test.R#9: f2(x)" and "Error occuring: Test.R#14: f(NULL)" means an error caused by a malfunction of the function f(NULL) on line 14, which refers to the function f2() on line 9
# Error tracing function withErrorTracing = function(expr, silentSuccess=FALSE) { hasFailed = FALSE messages = list() warnings = list() errorTracer = function(obj) {
Saving error position and message
We call the script TestError.R above and fix the printed result in a variable called errorStorage here, with which we can work later or just display.
errorStorage <- capture.output(tryCatch({ withErrorTracing({source("TestError.R")}) }, error = function(e){ e <<- e cat("ERROR: ", e$message, "\nin ") print(e$call) }))
Therefore, we store the value of e with the call and message, as well as with the location of the error location. The errorStorage output should be as follows:
[1] "[1] \"Error occuring: Test.R#9: f2(x)\" \"Error occuring: Test.R#14: f(NULL)\"" [2] "ERROR: argument is of length zero " [3] "in if (x == 1) \"foo\""
Hoping this can help.