You may have noticed that R sometimes gives you an error when you enter an invalid expression. For example:
> 12 / "hat"
Error in 12/"hat" : non-numeric argument to binary operator
Other times, R may just give you a warning:
> if (c(TRUE,FALSE)) TRUE else FALSE
[1] TRUE
Warning message:
In if (c(TRUE, FALSE)) TRUE else FALSE :
the condition has length > 1 and only the first element will be used
Like other modern programming languages, R includes the ability to signal exceptions when unusual events occur and catch to exceptions when they occur. If you are writing your own R programs, it is usually a good idea to stop execution when an error occurs and alert the user (or calling function). Likewise, it is usually a good idea to catch exceptions from functions that are called within your programs.
It might seem strange to talk about exception handling in the context of environments, but exception handling and environments are closely linked. When an exception occurs, the R interpreter may need to abandon the current function and signal the exception in the calling environment.
This section explains how the error-handling system in R works.
If something occurs in your code that requires you to stop
execution, you can use the stop
function. For example, suppose that you had written a
function called dowork(filename)
to
automatically generate some charts and save them to a file specified by
the argument filename
. Suppose that R
couldn’t write to the file, possibly because the directory didn’t
exist. To stop execution and print a helpful error message, you could
structure your code like this:
> doWork <- function(filename) { + if(file.exists(filename)) { + read.delim(filename) + } else { + stop("Could not open the file: ", filename) + } + } > doWork("file that doesn't exist") Error in doWork("file that doesn't exist") : Could not open the file: file that doesn't exist
If something occurs in your code that you want to tell the user
about, but which isn’t severe enough to normally stop execution, you can
use the warning
function. Reusing the example above, if the file
“filename” already exists, then the function will simply return the string
"la la la"
. If the file does not
exist, then the function will warn the user that the file does not
exist.
> doNoWork <- function(filename) { + if(file.exists(filename)) { + "la la la" + } else { + warning("File does not exist: ", filename) + } + } > doNoWork("another file that doesn't exist") Warning message: In doNoWork("another file that doesn't exist") : File does not exist: another file that doesn't exist
If you just want to tell the user something, then you can use the
message
function:
> doNothing <- function(x) { + message("This function does nothing.") + } > doNothing("another input value") This function does nothing.
Suppose that you are writing a function in R called
foo
that calls another function
called bar
. Furthermore, suppose that
bar
sometimes generates an error, but
you don’t want foo
to stop if the
error is generated. For example, maybe bar
tries to open a file but signals an error
when it can’t open the file. If bar
can’t open the file, maybe you want foo
to try doing something else
instead.
A simple way to do this is to use the try
function. This function hides some of the complexity of
R’s exception handling. Here’s an example of how to use try
:
> res <- try({x <- 1}, silent=TRUE) > res [1] 1 > res <- try({open("file that doesn't exist")}, silent=TRUE) > res [1] "Error in UseMethod(\"open\") : \n no applicable method for 'open' applied to an object of class \"character\"\n" attr(,"class") [1] "try-error"
The try
function takes two
arguments, expr
and silent
. The first argument, expr
, is the R expression to be tried (often a
function call). The second argument specifies whether the error message
should be printed to the R console (or stderr); the default is to print
errors. If the expression results in an error, then try
returns an object of class "try-error"
.
A more capable function is tryCatch
. The tryCatch
function
takes three sets of arguments: an expression to try, a set of handlers
for different conditions, and a final expression to evaluate. For
example, suppose that the following call was made to tryCatch
:
tryCatch(expression
,handler1
,handler2
, ..., finally=finalexpr
)
The R interpreter would first evaluate
. If a
condition occurs (an error or warning), R will pick the appropriate
handler for the condition (matching the class of the condition to the
arguments for the handler). After the expression has been evaluated,
expression
will be evaluated. (The handlers will not be active when this expression
is evaluated.)finalexpr