R Catching by Class
Catching by class gives tryCatch one handler for a named class of error. Each handler is a function named by the class it catches.
A class handler beats the general handler
raise_low raises a low_balance error and tryCatch holds both a low_balance handler and an error handler. The printed value comes from the low_balance handler.
raise_low <- function() {
stop(structure(
list(message = "balance too low", call = NULL),
class = c("low_balance", "error", "condition")
))
}
result <- tryCatch(raise_low(), low_balance = function(e) "low balance handler", error = function(e) "general handler")
print(result)A handler returns the message
raise_name raises a bad_name error with the message bad name. The bad_name handler returns conditionMessage as the value of the whole call.
raise_name <- function() {
stop(structure(
list(message = "bad name", call = NULL),
class = c("bad_name", "error", "condition")
))
}
msg <- tryCatch(raise_name(), bad_name = function(e) conditionMessage(e), error = function(e) "general handler")
print(msg)A different class falls through
raise_low raises a low_balance error again, but this tryCatch names a bad_name handler instead. The error falls through to the general error handler.
raise_low <- function() {
stop(structure(
list(message = "balance too low", call = NULL),
class = c("low_balance", "error", "condition")
))
}
result <- tryCatch(raise_low(), bad_name = function(e) "name handler", error = function(e) "general handler")
print(result)No error means no handler runs
The expression inside this tryCatch gives a plain value and raises nothing. The value passes through as the result and neither handler runs.
double <- function(x) {
x * 2
}
result <- tryCatch(double(21), low_balance = function(e) "low balance handler", error = function(e) "general handler")
print(result)Example
raise_low <- function() {
stop(structure(
list(message = "balance too low", call = NULL),
class = c("low_balance", "error", "condition")
))
}
raise_name <- function() {
stop(structure(
list(message = "bad name", call = NULL),
class = c("bad_name", "error", "condition")
))
}
first <- tryCatch(raise_low(), low_balance = function(e) conditionMessage(e), error = function(e) "general handler")
second <- tryCatch(raise_name(), low_balance = function(e) "low balance handler", error = function(e) "general handler")
print(first)
print(second)Key points
- A tryCatch handler named by a class catches errors of that class.
- A handler named with a custom class beats the general error handler for that class.
- The handler receives the condition as its argument.
- conditionMessage inside a handler reads the error text.
- The value a handler returns becomes the value of the whole tryCatch call.
- An error whose class matches no named handler falls through to the error handler.
In this example, the low_balance error meets its named handler, which returns the message text. The bad_name error has no named handler in the call, so it falls through to the general error handler.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท rdrr.io R Snippets
Exercise
A low_balance error is raised and tryCatch holds both a low_balance handler and an error handler. Which handler runs?