I believe this is the way try() has interacted with the traditional
error handling in R for many years, for better or worse. The check
for a try() on the stack, and jump to it if one is found, happens
before the traceback is written. In some cases this behavior is what
one wants, in others it may not be. Writing the traceback is also
turned off by defining an error option. That seems a bit less
sensible to me, but again has been that way for some time, and it may
be what is wanted in some cases.
The new error handling system is intended to provide more flexibility.
If you want to silence the error but capture traceback information you
can use a calling handler to capture the calls on the stack with
sys.calls and then jump to a restart. Something like this:
myTry <- function(expr) {
withRestarts(
withCallingHandlers(expr,
error = function(e) {
t <- sys.calls()
invokeRestart("myAbort", e, t)
}),
myAbort = function(e, t)
list(error = e, traceback = t))
}
[Because of lazy argumetn evaluation you have to force evaluation of t
in the handler.]
[It might be safer to use a restart naming convention like
"mypackage::myAport" to avoid conflicts.]
Then you get
> myTry(1+2)
[1] 3> myTry(f("A"))
$error
<simpleError in log(x): Non-numeric argument to mathematical function>
$traceback
$traceback[[1]]
myTry(f("A"))
$traceback[[2]]
withRestarts(withCallingHandlers(expr, error = function(e) {
t <- sys.calls()
invokeRestart("myAbort", e, t)
}), myAbort = function(e, t) list(error = e, traceback = t))
$traceback[[3]]
withOneRestart(expr, restarts[[1]])
$traceback[[4]]
doWithOneRestart(return(expr), restart)
$traceback[[5]]
withCallingHandlers(expr, error = function(e) {
t <- sys.calls()
invokeRestart("myAbort", e, t)
})
$traceback[[6]]
f("A")
$traceback[[7]]
log(a)
$traceback[[8]]
.handleSimpleError(function (e)
{
t <- sys.calls()
invokeRestart("myAbort", e, t)
}, "Non-numeric argument to mathematical function", quote(log(x)))
$traceback[[9]]
h(simpleError(msg, call))
You may want to trim some of the error handling internals out of the
sys.calls or something like that (we might want to think about
providing a function that does this at some point).
Hope that helps.
luke
On Thu, 11 Mar 2004, Edouard DUCHESNAY wrote:
> Hello,
>
> 1. The Situation :
> ------------------------
> The stack traceback is not available when error ouccured in a try(....)
> -- test.R --------------------------------
> f<-function(a){
> return ( log(a) )
> }
> try(f("A"))
> traceback()
> -------------------------------------------
>
> I get the following message :
> > try(f("A"))
> Error in log(x) : Non-numeric argument to mathematical function
> > traceback()
> No traceback available
>
> I try to use tryCatch(...) instead, I could get the stack traceback (using
the finally),
> but the R program stop.
>
> 2. My goal
> --------------------
> All I need is to prevent a error to stop a program (like try() does), print
the traceback
> just after the try(....), and get the error message (geterrmessage()).
>
>
> 3. Question
> -------------------
> A) stack traceback is not available when error ouccured in a try is a
normal behavior ?
> B) Do you have any sugestion to fill my goal ?
> C) If not is it a good idea to investigate around withRestarts(expr, ...) ?
>
>
> Best regards
>
>
> PS : My R Version 1.8.1 (2003-11-21)
>
--
Luke Tierney
University of Iowa Phone: 319-335-3386
Department of Statistics and Fax: 319-335-3017
Actuarial Science
241 Schaeffer Hall email: luke at stat.uiowa.edu
Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu