exiting {rlang} | R Documentation |
There are two types of condition handlers: exiting handlers, which
are thrown to the place where they have been established (e.g.,
with_handlers()
's evaluation frame), and local handlers, which
are executed in place (e.g., where the condition has been
signalled). exiting()
and calling()
create handlers suitable
for with_handlers()
.
exiting(handler) calling(handler)
handler |
A handler function that takes a condition as
argument. This is passed to |
A subtle point in the R language is that conditions are not thrown,
handlers are. base::tryCatch()
and with_handlers()
actually
catch handlers rather than conditions. When a critical condition is
signalled with base::stop()
or abort()
, R inspects the handler
stack and looks for a handler that can deal with the condition. If
it finds an exiting handler, it throws it to the function that
established it (with_handlers()
). That is, it interrupts the
normal course of evaluation and jumps to with_handlers()
evaluation frame (see ctxt_stack()
), and only then and there the
handler is called. On the other hand, if R finds a calling
handler, it executes it locally. The calling handler can choose to
handle the condition by jumping out of the frame (see rst_jump()
or return_from()
). If it returns locally, it declines to handle
the condition which is passed to the next relevant handler on the
stack. If no handler is found or is able to deal with the critical
condition (by jumping out of the frame), R will then jump out of
the faulty evaluation frame to top-level, via the abort restart
(see rst_abort()
).
exiting()
is in the questioning stage
because with_handlers()
now treats handlers as exiting by
default.
with_handlers()
for examples, restarting()
for another
kind of calling handler.
# You can supply a function taking a condition as argument: hnd <- exiting(function(c) cat("handled foo\n")) with_handlers(signal("A foobar condition occurred", "foo"), foo = hnd) # Or a lambda-formula where "." is bound to the condition: with_handlers(foo = calling(~cat("hello", .$attr, "\n")), { signal("A foobar condition occurred", "foo", attr = "there") "foo" })