๐ŸŽ“ A1Learner
๐Ÿ”
0 of 27 lessons completed

R Custom Conditions

A custom condition is an error that carries its own class name. The class name lets later code tell one kind of failure from another.

Raise through a helper

raise_low builds the classed condition and passes it to stop. tryCatch catches the error and conditionMessage reads the message back.

raise_low <- function() {
  stop(structure(
    list(message = "balance too low", call = NULL),
    class = c("low_balance", "error", "condition")
  ))
}
msg <- tryCatch(raise_low(), error = function(e) conditionMessage(e))
print(msg)

The class vector on the condition

The handler here returns the class of the caught condition. The print shows the custom name first, ahead of error and condition.

raise_low <- function() {
  stop(structure(
    list(message = "balance too low", call = NULL),
    class = c("low_balance", "error", "condition")
  ))
}
cls <- tryCatch(raise_low(), error = function(e) class(e))
print(cls)

The message field drives the text

raise_with takes the message as an argument and stores it in the condition list. The caught message is the longer text passed in the call.

raise_with <- function(message) {
  stop(structure(
    list(message = message, call = NULL),
    class = c("low_balance", "error", "condition")
  ))
}
msg <- tryCatch(raise_with("balance too low for rent"), error = function(e) conditionMessage(e))
print(msg)

An uncaught custom error

This call has no handler around it, so the script stops. The error prints as one line because the condition call is NULL.

raise_low <- function() {
  stop(structure(
    list(message = "balance too low", call = NULL),
    class = c("low_balance", "error", "condition")
  ))
}
raise_low()

Example

pay <- function(balance, amount) {
  if (balance < amount) {
    stop(structure(
      list(message = "balance too low", call = NULL),
      class = c("low_balance", "error", "condition")
    ))
  }
  balance - amount
}
print(pay(50, 20))
note <- tryCatch(pay(10, 20), error = function(e) conditionMessage(e))
print(note)

Key points

  • structure builds the condition value from a list and a class vector.
  • The list holds a message value and a call value set to NULL.
  • The class vector puts the custom name first, then error and condition.
  • stop raises the condition as an error.
  • A small helper function can build and raise the condition in one place.
  • conditionMessage reads the message text back from a caught condition.
  • With the call set to NULL, an uncaught custom error prints one line.

In this example, pay takes 20 from 50 and gives back 30. The second payment asks for more than the balance holds, so pay raises the custom condition and the handler reads its message back as text.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท rdrr.io R Snippets

Exercise

What does the first name in the class vector c("low_balance", "error", "condition") give the condition?