Henrik Bengtsson
2005-Sep-07 17:14 UTC
[Rd] Tracebacks with tryCatch() and withCallingHandlers()?
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
Kurt Hornik
2005-Sep-08 06:42 UTC
[Rd] Tracebacks with tryCatch() and withCallingHandlers()?
>>>>> Henrik Bengtsson writes:> 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?tools:::.try_quietly() tries doing something similar (catch errors and print a traceback) [the code is not necessarily a thing of beauty ...]. Hth Best -k