[Rd] Tracebacks with tryCatch() and withCallingHandlers()?
Henrik Bengtsson
hb at maths.lth.se
Wed Sep 7 19:14:37 CEST 2005
When batch processing analysis, I use tryCatch() for failure handling
and to prevent unwanted interrupts. I write detailed progress to log
file and conditions (warnings and errors) are written to the same log
file immediately by using withCallingHandlers(..., condition=function(c)
cat(c, file=logFile)). However, I would also like to write the call
stack to the log file to further simplify troubleshooting; traceback()
does unfortunately not work here. From ?traceback, we have
"Errors which are caught _via_ 'try' or 'tryCatch' do not generate a
traceback, so what is printed is the call sequence for the last uncaught
error, and not necessarily the last error."
(and it seems to be case for withCallingHandlers() too). Does anyone
know of a workaround for this? Is there a way to get the call stack
within the condition handler?
Example:
foo <- function() stop("whoops");
pre <- function() foo();
bar <- function() pre();
yo <- function(fcn=tryCatch) {
fcn(bar(),
error = function(ex) {
str(ex);
traceback(); # I would like to access the call stack here!
}
)
traceback();
}
Calling these gives:
> rm(.Traceback)
> yo() # Using tryCatch()
List of 2
$ message: chr "whoops"
$ call : language foo()
- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
No traceback available
No traceback available
> traceback()
No traceback available
The same, but now with withCallingHandlers(), which does not "prevent"
the error from interrupting the code, gives similar results
> rm(.Traceback)
> yo(fcn=withCallingHandlers)
List of 2
$ message: chr "whoops"
$ call : language foo()
- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
No traceback available
Error in foo() : whoops
> traceback()
5: stop("whoops")
4: foo()
3: bar()
2: fcn(bar(), error = function(ex) {
str(ex)
traceback()
})
1: yo(fcn = withCallingHandlers)
Traceback() is available if the error is "let through". I am also aware
that the 'call' element of the condition object reports "foo()", (which
is better than nothing). However, I am missing information on the
calling functions pre() and bar().
In addition to traceback(), I've also tried sys.calls(), sys.frames()
and sys.status(), but none of these seems to "report" that the error
occured inside foo(), instead you only get
$sys.calls
$sys.calls[[1]]
yo()
$sys.calls[[2]]
fcn(bar(), error = function(ex) {
str(ex)
traceback()
print(sys.status())
str(sys.calls())
str(sys.frames())
})
$sys.calls[[3]]
tryCatchList(expr, classes, parentenv, handlers)
...
Am I looking for something that I can't get? Would a solution be for R
to internally record the call stack as soon as a condition occurs/is
instanciated?
Thanks for enlightning me
Henrik
More information about the R-devel
mailing list