Skip to content
Prev 60539 / 63421 Next

[External] Re: message(<cond>) and warning(<cond>) circumvent calling handlers and signal the original class, e.g. an error

This is behaving as documented and as intended. If you want to
call stop() with a condition argument and you want to have that
condition handled as an error then you need to make sure that your
condition inherits from "error". One way to do this would be to define
something like

warningToError <- function(w)
    errorCondition(conditionMessage(w),
                   warning = w,
 		  class = "warningToError")

and use stop(warningToError(w)).

If you call stop() with a condition argument then that is the
condition stop() will signal, regardless of its class. I can't at the
moment think of a good reason why I would want to call stop() with a
warning condition argument, and I suspect most cases where that
happens would be mistakes. So checking in stop() that a condition
argument inherits from "error" and signaling a warning, or maybe an
error, if it does not might be worth considering (with analogous
changes for warning() and message()).

The condition system separates the signaling protocol from the process
of determining handlers. Signaling itself is done by
signalCondition().  message() and warning() signal a condition with a
muffle restart available, and return if the condition is not handled.
stop() is guaranteed not to return; if the condition is not handled,
then it invokes the default error handler, which will not return. None
of these currently look at the class of the condition.
signalCondition() looks at the condition's class to find out what
handlers are available. It will invoke error handlers for error
conditions and warning handlers for warning conditions.  It does not
know or care about whether it was called from stop(), warning(),
message(), or some other way.

The most common high-level usage of stop(), warning(), or message() is
to call them with a string and possibly some additional arguments used
to create a message. In these cases a condition object of class
"error" for stop(), "warning" for warning(), and "message" for message
is created implicitly and signaled.

Calling these functions with a condition argument is using lower level
functionality, which gives more power but also means users need to
understand what they are doing. In particular, users who want to call
stop() with a condition argument _and_ want handlers for error
conditions to be used need to make sure that the class of the
condition they signal inherits from "error".

Best,

luke
On Tue, 1 Mar 2022, Andreas Kersting wrote: