conditions
Condition Handling and Recovery

Description

These functions provide a mechanism for handling unusual conditions, such as warnings and errors.

Usage

computeRestarts(cond = NULL)
conditionCall(c)
conditionMessage(c)
findRestart(name, cond = NULL)
invokeRestart(r, ...)
tryInvokeRestart(r, ...)
invokeRestartInteractively(r)
isRestart(x)
restartDescription(r)
restartFormals(r)
signalCondition(cond)
simpleCondition(message, call = NULL)
simpleError(message, call = NULL)
simpleWarning(message, call = NULL)
simpleMessage(message, call = NULL)
errorCondition(msg, ..., class = NULL, call = NULL)
warningCondition(msg, ..., class = NULL, call = NULL)
tryCatch(expr, ..., finally)
withCallingHandlers(expr, ...)
globalCallingHandlers(...)
withRestarts(expr, ...)
.signalSimpleWarning(msg, call)
.handleSimpleError(h, msg, call)
## S3 method for class 'condition':
as.character(x, ...)
## S3 method for class 'error':
as.character(x, ...)
## S3 method for class 'condition':
conditionCall(c)
## S3 method for class 'condition':
conditionMessage(c)
## S3 method for class 'condition':
print(x, ...)
## S3 method for class 'restart':
print(x, ...)

Arguments

cond a condition object.
ca list object of class "condition" with the component call.
namea character string. Specifies the name of restart.
ra character string, usually an object of class restart.
xany object.
messagea character string.
calla character string.
expran expression to be evaluated.
finallyan expression to be evaluated before returning.
msga character string.
ha function name.
...additional arguments.

Details

The condition system supports registering functions that are called when unusual conditions occur, such as errors, warnings, and messages. These functions can examine the condition that occurred without altering the normal program execution, or transfer control to a particular function executing on the stack, such as the "try...catch" statements in some languages.
Using Condition Handlers
The following functions are used to create condition handlers and to signal conditions.

withCallingHandlers(expr, ...) Evaluates the expression expr and returns its value, after setting up condition handlers as specified by its ... arguments. Each of these arguments should be given with a name specifying which condition to handle, and a condition handler function with a single argument.

When a condition is signalled, each active condition handler is examined in order down the execution stack from most recently created to least. If the signalled condition object (described below) matches the specified condition name (that is, the condition name appears in the class list of the condition object), the condition handler function is called with one argument: the condition object. If the condition handler function returns, its value is ignored and the remaining condition handlers are examined in order. If a matching condition handler does not return, by calling invokeRestart or stop or signalling another condition, this terminates the condition handler scan.

The condition handlers within a withCallingHandlers call are examined in the order they are specified. Multiple handlers can have the same name: they will be executed in that order. If a condition handler function signals another condition, the active conditions that will be examined are those defined after the executing condition handler in the withCallingHandlers call, or later on the execution stack. Thus, a condition handler function can signal the same type of condition without calling itself recursively.

tryCatch(expr, ..., finally) Similar to withCallingHandlers, in that it evaluates the expression expr and returns its value, after setting up condition handlers as specified by its ... arguments. However, if one of its condition handler functions is selected, the execution stack is unwound to the tryCatch function, then the condition handler function is executed and its value is returned from tryCatch (rather than the value of expr). Another difference is the additional argument finally. If the finally argument is specified, it is evaluated just before tryCatch returns, whether it returns normally, or whether it is popped from the execution stack by throwing a condition or invoking a restart handler. This can be used like on.exit to execute cleanup expressions.
signalCondition(cond) Takes a condition object (described below) specifying an event, and signals this condition, scanning the condition handlers defined by withCallingHandlers and tryCatch functions as described above. If the cond argument is not a condition object, it is converted to a character, and passed to simpleCondition to construct a condition object. If the execution stack is not unwound by a condition handler, signalCondition returns NULL. In many cases, it is not necessary to explicitly signal conditions, since conditions are automatically signalled by the stop, warning and message functions.
globalCallingHandlers(...) Establish global condition handlers as specified by its ... arguments, and return NULL. These condition handlers are examined in order after any handlers defined in an active withCallingHandlers call. These handlers are added before any previously-defined global handlers. If any handler is added with the same class name and function, the existing handler is removed, and a message is generated.

globalCallingHandlers acts differently in a few special cases: If globalCallingHandlers is called with a single list element, this list is used to specify the handlers to add. Calling globalCallingHandlers(NULL) removes all global handlers, and returns a list of the handler functions before they were removed. Calling globalCallingHandlers() returns a list of the currently-defined global handler functions.

Note: Global handlers can not be changed while there are active non-global handlers defined by withCallingHandlers or tryCatch. globalCallingHandlers will generate an error if it is called while there are any such active handlers.

Using Restarts
Restart handlers are similar to condition handlers, but there are some differences in the way that they are specified and the way restart handler functions are called. The function withRestarts is similar to tryCatch in that the execution stack is unwound when a restart handler is executed, but the matching restart function will be passed one or more extra arguments specified when the restart is invoked. Also, an error occurs if a restart name is invoked and there is no matching restart function.

withRestarts(expr, ...) Evaluates the expression expr and returns its value, after setting up restart handlers as specified by its ... arguments. Each of these arguments should be given with a name specifying a restart name, and a restart handler function with zero or more arguments. A restart handler can also be specified as a list with any of the elements of a restart object, which will be used to constructing the restart handler.

Restart handlers are scanned in the same order as condition handlers, in the order specified within the withRestarts function call, and then in order down the execution stack. Similar to condition handlers, a restart handler function can invoke a restart, which examines restart handlers after the executing restart handler.

invokeRestart(r, ...) Invokes a restart with the name given by r. The r argument can be a string or a restart object (defined below) whose name is extracted. The invokeRestart function first examines the currently active restarts to find the first one whose name is the same name as r. If none is found, this generates an error. If a restart is found, the execution stack is unwound to the defining withRestarts function, and the restart handler function is executed, passing the extra arguments specified by the ... arguments to invokeRestart. Then, the value of the restart handler function is returned as the value of the withRestarts function.
tryInvokeRestart(r, ...) Invokes a named restart just like invokeRestart, except that if no matching restart is found, it just silently returns NULL without generating an error.
invokeRestartInteractively(r) Invokes the named restart just like invokeRestart, after asking the user to interactively specify the values of each of the arguments that will be passed to the restart handler function. Each typed argument is evaluated, so it can include expressions in addition to constant values. If the engine is not running in interactive mode (see interactive), invokeRestartInteractively generates an error.
findRestart(name, cond = NULL) Searches the currently-active restart objects, and returns the first one with the matching name. If no matching restart is found, this returns NULL. The cond argument is currently not used.
computeRestarts(cond = NULL) Returns a list of the currently-active restart objects. The last element of this list is always an "abort" restart defined at the top-level. The cond argument is currently not used.
Error Handling and the Condition System
When an error occurs during program execution, through an explicit call to the stop function, or when other internal errors occur, it is processed as follows:
  1. A simpleError condition is signalled containing the error message. This will execute "error" condition handlers created by withCallingHandlers or throw to an "error" condition handler created by tryCatch. The "error" condition may also be caught by try, which is implemented using tryCatch.
  2. If there is an "abort" restart defined (other then the default top-level "abort" restart), it will be invoked.
  3. If control has not been transferred to tryCatch or withRestarts, then normal error processing occurs, printing the error and collecting the stack trace for traceback.

    Out-of-memory errors are handled a little differently from other errors: They will be caught by tryCatch with an "error" handler or try, but will not execute "error" condition handlers created by withCallingHandlers, or capture the stack trace for the error.

Warnings and Messages and the Condition System

The warning and message functions both signal specific conditions, and their behavior can be modified by invoking particular restarts.

  • When the warning function is called, it creates and signals a simpleWarning condition containing the warning message. This executes "warning" condition handlers created by withCallingHandlers. If a condition handler invokes a restart named "muffleWarning", the warning is not printed or saved. tryCatch can also be used to catch "warning" conditions.
  • In a similar way, when the message function is called, it creates and signals a simpleMessage condition containing the message. This executes "message" condition handlers created by withCallingHandlers. If a condition handler invokes a restart named "muffleMessage", the message is not printed. tryCatch can also be used to catch "message" conditions.
The packageStartupMessage function is almost the same as message, except that it signals a condition created by .packageStartupMessage, which can invoke conditions with class "packageStartupMessage" in addition to "message". As with message, if a condition handler invokes a restart named "muffleMessage", the message is not printed.
Interrupts and the Condition System

Typing control-C causes an interrupt, which normally stops the executing computation and returns to the top-level console. An interrupt signals a condition with class c("interrupt","condition"), and its behavior can be modified by invoking a restart.

tryCatch and withCallingHandlers can define handlers for an "interrupt" condition. If withCallingHandlers defines an interrupt condition handler that invokes a restart named "resume", the interrupted computation is resumed.

If the interrupt option (see options) specifies a function, it will be called with no arguments if an interrupt condition is not caught. If this function invokes a restart named "resume", the interrupted computation is resumed.

Condition Objects
A condition object is a list with elements named "message" and "call", whose class is a vector of classes including the class "condition". The "message" element is typically a message string, such as a warning message. The "call" element is usually either NULL or the call expression that was executing when the condition event occurred. Most conditions specify additional classes in addition to "condition", to give more information about the event. A condition handler defined by withCallingHandlers or tryCatch can be matched by any of the classes in the condition object class list.

The following functions create and manipulate "condition" objects, which represent an event which has occurred:

simpleCondition(message, call = NULL) Returns a condition object with class c("simpleCondition", "condition"), with the specified message and call elements.
simpleError(message, call = NULL) Returns a condition object with class c("simpleError", "error", "condition").
simpleWarning(message, call = NULL) Returns a condition object with class c("simpleWarning", "warning", "condition").
simpleMessage(message, call = NULL) Returns a condition object with class c("simpleMessage", "message", "condition").
errorCondition(msg, ..., class = NULL, call = NULL) Returns a condition object with class c(class, "error", "condition") and the specified call and message. The ... arguments are also added to the condition object.
warningCondition(msg, ..., class = NULL, call = NULL) Returns a condition object with class c(class, "message", "condition") and the specified call and message. The ... arguments are also added to the condition object.
conditionCall(c) S3 generic functions for extracting the message and call elements from any object, with methods conditionCall.condition and conditionMessage.condition defined for accessing condition objects.
conditionCall.condition(c)
conditionMessage(c)
conditionMessage.condition(c)
as.character.condition(x, ...) The S3 methods as.character.condition, as.character.error, and print.condition define convenient printed text for condition objects.
as.character.error(x, ...)
print.condition(x, ...)
Restart Objects
A restart object is a list with class "restart" and the following named elements:

  • "name": a string giving the name of the restart.
  • "exit": NULL (this element is an environment in R).
  • "handler": the restart handler function.
  • "description": a description string.
  • "test": a function.
  • "interactive": NULL.
isRestart(x) Returns TRUE if the argument x has class restart, regardless of whether it contains all of the elements above.
restartDescription(r) returns the "description" element of a restart object.
restartFormals(r) Returns the formals of the handler element of a restart object.
print.restart(x, ...) An S3 function. Prints a restart object in a useful form.
Miscellaneous Functions
The following functions were implemented for compatibility with R, where they are probably used for implementing some elements of the condition system.

.signalSimpleWarning(msg, call) Similar to warning. It generates a warning with the specified message and call object, handling "warning" condition handlers and printing or saving the warning. It returns NULL.
.handleSimpleError(h, msg, call) Constructs a simpleError condition object, calls the function h (which must be a function object, not a name or string), and returns the value returned by the function h.
Value
See descriptions of the individual functions in the "details" section.
References
The tryCatch mechanism is similar to Java error handling. Calling handlers and restarts are loosely based on Common Lisp and Dylan.
See Also
stop, warnings, message, try, options, on.exit.
Examples

# create an "error" condition handler, called when processing error withCallingHandlers(stop("xyz"), error=function(e) cat("<error>")) # prints <error>, then processes the error as normal

# multiple condition handlers can match same condition, # matching different names in the simpleError condition object. withCallingHandlers(stop("xyz"), simpleError=function(e) cat("<simpleError>"), condition=function(e) cat("<condition>")) # prints <simpleError><condition>, then processes the error as normal

# signalling a condition within a condition handler will scan # handlers starting after the current handler withCallingHandlers(stop("xyz"), simpleError=function(e) {cat("<simpleError>");signalCondition(e)}, condition=function(e) cat("<condition>")) # prints <simpleError><condition><condition>, # then processes the error as normal

# tryCatch will "catch" its first matching condition handler # and return its result tryCatch(stop("xyz"), error=function(e) {cat("<error>");123L}, condition=function(e) {cat("<condition>");456L}) # prints <error>, then returns 123L without processing the error

# nest withCallingHandlers within tryCatch tryCatch(withCallingHandlers(stop("xyz"), simpleError=function(e) {cat("<simpleError>");signalCondition(e)}, condition=function(e) cat("<condition>")), error=function(e) {cat("<error>");123L}) # prints <simpleError><condition><error>, # then returns 123L without processing the error

# the tryCatch "finally" expression is evaluated when tryCatch returns tryCatch(stop("xyz"), error=function(e) {cat("<error>");123L}, finally=cat("<finally>")) # prints <error><finally>, # then returns 123L without processing the error

# the tryCatch "finally" expression is evaluated when tryCatch returns, # even if no condition handlers are caught tryCatch({cat("<expr>");999L}, error=function(e) {cat("<error>");123L}, finally=cat("<finally>")) # prints <expr><finally>, then returns 999L

# use signalCondition to throw user-defined condition myCondition <- function(message, call=NULL) structure(list(message=message, call=call), class=c("myCondition", "condition")) tryCatch(signalCondition(myCondition("foo")), myCondition=function(cond) {cat("<my>");123L}) # prints <my>, and returns 123L

# invokeRestart gives an error if a named restart is not found withRestarts(invokeRestart("noSuchRestart", 123L, 456L), foo=function(a,b) c(a,b)) # produces an error: restart not found

# call invokeRestart to jump to restart handler, passing arguments withRestarts({cat("<start>");invokeRestart("foo", 123L, 456L);789L}, foo=function(a,b) c(a,b)) # prints <start>, then returns c(123L, 456L)

# restart handler can be specified as a list with restart object fields withRestarts({cat("<start>");invokeRestart("foo", 123L, 456L);789L}, foo=list(description="my handler", handler=function(a,b) c(a,b))) # prints <start>, then returns c(123L, 456L)

# a restart handler can invoke another one passing different arguments withRestarts({cat("<start>");invokeRestart("foo", 123L, 456L);789L}, foo=function(a,b) {cat("<first>");invokeRestart("foo", a+1, b+1)}, foo=function(a,b) {cat("<second>");c(a,b)}) # prints <start><first><second>, then returns c(124L, 457L)

# call invokeRestartInteractively to interactively specify restart arguments withRestarts(invokeRestartInteractively("foo"), foo=function(a,b) c(a,b)) # displayed text, entering "123" and "4+5" as values: # Enter values for restart arguments: # # a: 123 # b: 4+5 # [1] 123 9

# searching for a restart, when none is defined withRestarts(findRestart("noSuchRestart"), foo=function(a,b) c(a,b)) # returns NULL, since there is no restart with name "noSuchRestart"

# searching for a defined restart withRestarts(findRestart("foo"), foo=function(a,b) c(a,b)) # returns a list object with class "restart", and including # elements name="foo" and handler=function(a,b) c(a,b)

# find all active restarts withRestarts(computeRestarts(), foo=function(a,b) c(a,b)) # returns a list with a restart named "foo", and ending with # the top-level "abort" restart.

# warning function signals simpleWarning condition withCallingHandlers({warning("foo");123L}, warning=function(e) {cat("<warn>")}) # prints <warn>, prints warning "foo", then returns 123L.

# invoke "muffleWarning" restart to prevent printing warning withCallingHandlers({warning("foo");123L}, warning=function(e) { cat("<warn>") invokeRestart("muffleWarning") }) # prints <warn>, then returns 123L.

# message function signals simpleMessage condition withCallingHandlers({message("foo");123L}, message=function(e) {cat("<msg>")}) # prints <msg>, prints message "foo", then returns 123L.

# invoke "muffleMessage" restart to prevent printing message withCallingHandlers({message("foo");123L}, message=function(e) { cat("<msg>") invokeRestart("muffleMessage") }) # prints <msg>, then returns 123L.

# can muffle packageStartupMessage message without muffling other messages withCallingHandlers({message("foo");packageStartupMessage("bar");123L}, packageStartupMessage=function(e) { cat("<msg>") invokeRestart("muffleMessage") }) # print message "foo", then <msg>, then return 123L

# define an interrupt condition handler to resume an interupted computation withCallingHandlers(for(x in 1:10){print(x);Sys.sleep(1)}, interrupt=function(ex){cat("<interrupt>");invokeRestart("resume")}) # on an interrupt, print <interrupt> and continue the loop

Package base version 6.1.4-13
Package Index