with_abort() promotes conditions as if they were thrown with abort(). These errors embed a backtrace. They are particularly suitable to be set as parent errors (see parent argument of abort()).

with_abort(expr, classes = "error")

Arguments

expr

An expression run in a context where errors are promoted to rlang errors.

classes

Character vector of condition classes that should be promoted to rlang errors.

Details

with_abort() installs a calling handler for errors and rethrows non-rlang errors with abort(). However, error handlers installed within with_abort() have priority. For this reason, you should use tryCatch() and exiting handlers outside with_abort() rather than inside.

Examples

# For cleaner backtraces: options(rlang_trace_top_env = current_env()) # with_abort() automatically casts simple errors thrown by stop() # to rlang errors: fn <- function() stop("Base error") try(with_abort(fn()))
#> Error : Base error #> Backtrace: #> █ #> 1. ├─base::try(with_abort(fn())) #> 2. │ └─base::tryCatch(...) #> 3. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 4. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 5. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 6. ├─rlang::with_abort(fn()) #> 7. │ └─base::withCallingHandlers(...) #> 8. └─global::fn()
#> <error> #> message: Base error #> class: `rlang_error` #> backtrace: #> 1. base::try(with_abort(fn())) #> 8. global::fn() #> Call `rlang::last_trace()` to see the full backtrace
# with_abort() is handy for rethrowing low level errors. The # backtraces are then segmented between the low level and high # level contexts. low_level1 <- function() low_level2() low_level2 <- function() stop("Low level error") high_level <- function() { with_handlers( with_abort(low_level1()), error = ~ abort("High level error", parent = .x) ) } try(high_level())
#> Error : High level error #> Parents: #> ─Low level error #> Backtrace: #> █ #> 1. ├─base::try(high_level()) #> 2. │ └─base::tryCatch(...) #> 3. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 4. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 5. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 6. └─global::high_level() #> 7. ├─rlang::with_handlers(...) #> 8. │ └─base::tryCatch(...) /home/travis/build/r-lib/rlang/R/cnd-handlers.R:100:2 #> 9. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 10. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 11. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 12. ├─rlang::with_abort(low_level1()) #> 13. │ └─base::withCallingHandlers(...) #> 14. └─global::low_level1() #> 15. └─global::low_level2()
#> <error> #> message: High level error #> class: `rlang_error` #> backtrace: #> 1. base::try(high_level()) #> 6. global::high_level() #> <error: parent> #> message: Low level error #> class: `rlang_error` #> backtrace: #> 1. rlang::with_abort(low_level1()) #> 3. global::low_level1() #> 4. global::low_level2() #> Call `rlang::last_trace()` to see the full backtrace
#> <error> #> message: High level error #> class: `rlang_error` #> fields: `message`, `trace`, and `parent` #> backtrace: #> █ #> 1. ├─base::try(high_level()) #> 2. │ └─base::tryCatch(...) #> 3. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 4. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 5. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 6. └─global::high_level() #> <error: parent> #> message: Low level error #> class: `rlang_error` #> fields: `message`, `trace`, `parent`, and `error` #> backtrace: #> █ #> 1. ├─rlang::with_abort(low_level1()) #> 2. │ └─base::withCallingHandlers(...) #> 3. └─global::low_level1() #> 4. └─global::low_level2()
# Reset to default options(rlang_trace_top_env = NULL)