The key C function that powers both tryCatch()
and withCallingHandlers()
is do_addCondHands()
. It creates handler object with mkHandlerEntry()
then stores in the handler stack for the current frame. (More precisely it writes to R_HandlerStack
, a global variable that is an alias to c->handlerstack
)
The five R arguments to do_addCondHands()
are classes
, handlers
, parentenv
, target
, and calling
. These are combined with a result
object (a list of length 4, returned by the exiting handler to doTryCatch()
) to create the handler objects which have five components:
-
The
class
, accessed withENTRY_CLASS(e)
. A string given a class name; the handler will match all conditions that contain this component in their class vector. -
The
handler
, accessed withENTRY_HANDLER(e)
. This is the function called with the condition object. It can also beR_RestartToken
, used as part of the restarts system. -
The
parentenv
, accessed withENTRY_CALLING_ENVIR(e)
. This does not appear to be used. -
The
target
environment, accessed withENTRY_TARGET_ENVIR(e)
, is only set bytryCatch()
. This is used to find the frame that the handler will return to. -
The
calling
flag, accessed withIS_CALLING_ENTRY(e)
determines if this is a calling/in-place handler (TRUE
) or an exiting handler (FALSE
).
There are four ways for a condition to be signalled:
-
With
stop()
which callsvsignalError()
. -
With an interrupt, which triggers
signalInterrupt()
-
With
warning()
, which callsvsignalWarning()
, which then callsvwarningcall_dflt()
. (This is particularly complicated because warnings are usually cached and only shown after the top level execution completes.) -
With
signalCondition()
, which callsdo_signalCondition()
(message()
callssignalCondition()
with a default handler thatcat()
s the message tostderr()
.)
Each of C signalling functions works similarly. It finds a matching handler in R_HandlerStack
, using findConditionHandler()
or similar, and then either calls it or calls gotoExitingHandler
.