@AllanCamerons answer already answers my question in a very elegant way. However, there's one problem that kept bugging me: The function signals both a message and an error. After studying the source code of rlang::signal_abort()
, I found that a mix of signalCondition()
and cat()
mostly mirrors the behavior of rlang::abort()
:
abort <- function(msg, call = sys.call(1)) {
cnd <- errorCondition(msg, call = call)
signalCondition(cnd)
msg <- sprintf("Error in %s:\n- %s", deparse(call), msg)
cat(msg, "\n", file = stderr())
old_options <- options(show.error.messages = FALSE)
on.exit(options(old_options))
stop("")
}
What (I think) this does:
signalCondition(cnd)
is where the error condition is signaled and specifies the "official" error message (as caught condition handlers) but does not abort execution.cat(..., file = stderr())
prints to stderr but does not signal a message.stop("")
aborts execution but neither signals another error (as this is already done earlier) nor prints an error message (as it is suppressed).Why this is useful:
> tryCatch(abort("something went wrong"), message = \(e) "message caught!")
# Error in tryCatch(abort("something went wrong"), message = function(e) "message caught!"):
# - something went wrong
> tryCatch(abort("something went wrong"), error = \(e) "error caught!")
# [1] "error caught!"
> try(abort("something went wrong"))
# Error : something went wrong