R: Signal a condition

cnd_signal {rlang} | R Documentation

## Signal a condition

### Description

Signal a condition to handlers that have been established on the stack. Conditions signalled with `cnd_signal()` are assumed to be benign. Control flow can resume normally once the conditions has been signalled (if no handler jumped somewhere else on the evaluation stack). On the other hand, `cnd_abort()` treats the condition as critical and will jump out of the distressed call frame (see `rst_abort()`), unless a handler can deal with the condition.

### Usage

    cnd_signal(.cnd, ..., .msg = NULL, .call = NULL, .mufflable = TRUE)

    cnd_inform(.cnd, ..., .msg = NULL, .call = NULL, .mufflable = FALSE)

    cnd_warn(.cnd, ..., .msg = NULL, .call = NULL, .mufflable = FALSE)

    cnd_abort(.cnd, ..., .msg = NULL, .call = NULL, .mufflable = FALSE)

### Arguments

`.cnd` | Either a condition object (see `cnd()`), or the name of a s3 class from which a new condition will be created.
`...` | Named data fields stored inside the condition object. These dots are evaluated with explicit splicing.
`.msg` | A string to override the condition's default message.
`.call` | Whether to display the call of the frame in which the condition is signalled. If `TRUE`, the call is stored in the `call` field of the condition object: this field is displayed by R when an error is issued. If a number `n`, the call is taken from the nth frame on the call stack. If `NULL`, the call is taken from the `.call` field that was supplied to the condition constructor (e.g. `cnd()`). In all cases the `.call` field is updated with the actual call.
`.mufflable` | Whether to signal the condition with a muffling restart. This is useful to let `inplace()` handlers muffle a condition. It stops the condition from being passed to other handlers when the inplace handler did not jump elsewhere. `TRUE` by default for benign conditions, but `FALSE` for critical ones, since in those cases execution should probably not be allowed to continue normally.

### Details

If `.critical` is `FALSE`, this function has no side effects beyond calling handlers. In particular, execution will continue normally after signalling the condition (unless a handler jumped somewhere else via `rst_jump()` or by being `exiting()`). If `.critical` is `TRUE`, the condition is signalled via `base::stop()` and the program will terminate if no handler dealt with the condition by jumping out of the distressed call frame.

`inplace()` handlers are called in turn when they decline to handle the condition by returning normally. However, it is sometimes useful for an inplace handler to produce a side effect (signalling another condition, displaying a message, logging something, etc), prevent the condition from being passed to other handlers, and resume execution from the place where the condition was signalled. The easiest way to accomplish this is by jumping to a restart point (see `with_restarts()`) established by the signalling function. If `.mufflable` is `TRUE`, a muffle restart is established. This allows inplace handler to muffle a signalled condition. See `rst_muffle()` to jump to a muffling restart, and the `muffle` argument of `inplace()` for creating a muffling handler.

### See Also

`abort()`, `warn()` and `inform()` for signalling typical R conditions. See `with_handlers()` for establishing condition handlers.

### Examples

    # Creating a condition of type "foo"
    cnd <- cnd("foo")

    # If no handler capable of dealing with "foo" is established on the
    # stack, signalling the condition has no effect:
    cnd_signal(cnd)

    # To learn more about establishing condition handlers, see
    # documentation for with_handlers(), exiting() and inplace():
    with_handlers(cnd_signal(cnd),
      foo = inplace(function(c) cat("side effect!\n"))
    )

    # By default, cnd_signal() creates a muffling restart which allows
    # inplace handlers to prevent a condition from being passed on to
    # other handlers and to resume execution:
    undesirable_handler <- inplace(function(c) cat("please don't call me\n"))
    muffling_handler <- inplace(function(c) {
      cat("muffling foo...\n")
      rst_muffle(c)
    })

    with_handlers(foo = undesirable_handler,
      with_handlers(foo = muffling_handler, {
        cnd_signal("foo")
        "return value"
      }))

    # cnd_warn() and cnd_inform() signal a condition and display a
    # warning or message:
    ## Not run:
    cnd_inform(cnd)
    cnd_warn(cnd)

    ## End(Not run)

    # You can signal a critical condition with cnd_abort(). Unlike
    # cnd_signal() which has no side effect besides signalling the
    # condition, cnd_abort() makes the program terminate with an error
    # unless a handler can deal with the condition:
    ## Not run:
    cnd_abort(cnd)

    ## End(Not run)

    # If you don't specify a .msg or .call, the default message/call
    # (supplied to cnd()) are displayed. Otherwise, the ones
    # supplied to cnd_abort() and cnd_signal() take precedence:
    ## Not run:
    critical <- cnd("my_error",
      .msg = "default 'my_error' msg",
      .call = quote(default(call))
    )
    cnd_abort(critical)
    cnd_abort(critical, .msg = "overridden msg")

    fn <- function(...) {
      cnd_abort(critical, .call = TRUE)
    }
    fn(arg = foo(bar))

    ## End(Not run)

    # Note that by default a condition signalled with cnd_abort() does
    # not have a muffle restart. That is because in most cases,
    # execution should not continue after signalling a critical
    # condition.

[Package rlang version 0.2.2 Index]