R (4.6) Module 4 – Control flow, functions and errors
Errors, warnings and condition handling
Signal errors, warnings and messages in R, recover with tryCatch(), log and go on with withCallingHandlers(), clean up with on.exit(), and catch by class.
What you will learn
- Use stop(), warning() and message() to report errors, problems and progress
- Recover with tryCatch(), log and continue with withCallingHandlers(), and clean up with on.exit()
- Create classed conditions and handle them by class while other errors propagate
- Decide whether to handle, suppress, convert or let a condition propagate
Before you start
What you’ll learn · Before you start
What you will learn
- Use stop(), warning() and message() to report errors, problems and progress
- Recover with tryCatch(), log and continue with withCallingHandlers(), and clean up with on.exit()
- Create classed conditions and handle them by class while other errors propagate
- Decide whether to handle, suppress, convert or let a condition propagate
Before you start
On this page
as.numeric(c("1200", "1,500", "n/a", "980")) gives 1200 NA NA 980 and one warning, “NAs introduced by coercion”,
which says neither how many values failed nor which. Whether a script stops there, logs the two bad values and goes
on, or hides the warning altogether is the job of R’s conditions: the errors, warnings and messages that code signals,
and the handlers that decide what the code does then.
On runs of R 4.6.1 you will signal each kind with stop(), warning() and message(), recover with tryCatch(), log
and carry on with withCallingHandlers(), close files with on.exit() whatever happens, and build errors of your own
class that a handler can catch while every other error still stops the program.
stop() ends, warning() complains, message() informs
check_age(-3) stopped with “age must not be negative, not -3”, while mean_positive(c(4, -1, 8)) returned 6 and
warned that it had ignored 1 negative value. The three functions differ in what follows them, and that is how to
choose between them:
| Function | What follows | Use it for |
|---|---|---|
stop() |
the call ends, and the error goes up to the caller | input the function cannot work with |
warning() |
the function goes on, and R prints the warning | a result that is valid but suspect |
message() |
the function goes on, and R prints the text | progress and information |
The run signals each one and prints the class of the condition: The object R signals to report an error, a warning or a message. It holds a message and the call, and its class vector, such as simpleError, error and condition, is what handlers choose by. it creates:
from session import run, version
version()
# R reads signals.R as if each line were typed at the console.
run("""
R --vanilla --quiet -f signals.R
""") Output
# R version 4.6.1 -- "Happy Hop"
$ R --vanilla --quiet -f signals.R
> # stop() ends the function with an error.
> check_age <- function(age) {
+ if (age < 0) stop("age must not be negative, not ", age)
+ age
+ }
> try(check_age(-3))
Error in check_age(-3) : age must not be negative, not -3
> # warning() reports a problem and lets the function finish.
> mean_positive <- function(x) {
+ if (any(x < 0)) warning("ignoring ", sum(x < 0), " negative values")
+ mean(x[x >= 0])
+ }
> mean_positive(c(4, -1, 8))
[1] 6
Warning message:
In mean_positive(c(4, -1, 8)) : ignoring 1 negative values
> # message() reports progress, which is not a problem at all.
> load_rows <- function(n) {
+ message("reading ", n, " rows")
+ seq_len(n)
+ }
> rows <- load_rows(3)
reading 3 rows
> # Each one signals a condition object with a class.
> class(tryCatch(stop("e"), error = function(e) e))
[1] "simpleError" "error" "condition"
> class(tryCatch(warning("w"), warning = function(w) w))
[1] "simpleWarning" "warning" "condition"
> class(tryCatch(message("m"), message = function(m) m))
[1] "simpleMessage" "message" "condition"
> # call. = FALSE leaves the call out of the message.
> check_age2 <- function(age) {
+ if (age < 0) stop("age must not be negative", call. = FALSE)
+ age
+ }
> try(check_age2(-3))
Error : age must not be negative
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 signals_session.py
The help page ?conditions describes the class vectors the run printed: every condition inherits from condition,
errors and warnings from error and warning, and stop(), warning() and message() use the classes
simpleError, simpleWarning and simpleMessage. Handlers choose
by these classes, as the rest of the lesson shows. Two details are visible in the run. The warning came after the
result: at the top level, R prints a warning when the call that raised it has finished, with that call in the text,
“In mean_positive(c(4, -1, 8))”. And call. = FALSE left the call out of the error, “Error : age must not be
negative”, which reads better for users of a function than a call they never typed.
Write the message for the person who will read it
Say what was wrong and what was expected, and include the value: “age must not be negative, not -3” can be fixed without opening the code; “invalid input” cannot.
tryCatch() stops the expression and returns the handler’s value
to_number("12,5") returned NA and a message instead of a bare warning: inside it,
tryCatch(as.numeric(text), warning = function(w) ...) caught the warning and returned the handler’s value. The help
page ?conditions says that when a condition matches a handler of tryCatch(), control is transferred to the
tryCatch() call, the handler is called with the condition, and its result becomes the value of tryCatch(). A
handler of this kind is an exiting handler: A handler set up by tryCatch(). When its condition is signalled, R abandons the expression, runs the handler, and returns the handler's value from tryCatch().: the expression is abandoned at the
point of the condition. Step through it:
The drawing shows the whole scene; its 5 steps are listed below.
Every step as text
- Run the expression. tryCatch() first records which conditions it handles, here warnings, and then evaluates the expression as.numeric("12,5").
- A warning is signalled. "12,5" is not a number in R, so as.numeric() signals the warning "NAs introduced by coercion".
- The expression is abandoned. tryCatch() has a handler for warnings, so R leaves the expression at once. Whatever came after as.numeric() would never run.
- The handler runs. tryCatch() calls the handler with the condition. It prints the message with conditionMessage(w) and returns NA_real_.
- The handler's value is returned. The value of the handler becomes the value of tryCatch(), so to_number("12,5") returns NA. A finally expression would run now, last of all.
The run shows the handler’s value, the abandoned expression, finally and the call that signalled:
from session import run, version
version()
# R reads trycatch.R as if each line were typed at the console.
run("""
R --vanilla --quiet -f trycatch.R
""") Output
# R version 4.6.1 -- "Happy Hop"
$ R --vanilla --quiet -f trycatch.R
> # tryCatch() returns the handler's value when a condition it handles is signalled.
> to_number <- function(text) {
+ tryCatch(
+ as.numeric(text),
+ warning = function(w) {
+ message("could not read '", text, "': ", conditionMessage(w))
+ NA_real_
+ }
+ )
+ }
> to_number("12.5")
[1] 12.5
> to_number("12,5")
could not read '12,5': NAs introduced by coercion
[1] NA
> # The expression stops at the condition: nothing after it runs.
> tryCatch({
+ x <- as.numeric("abc")
+ cat("this line never runs\n")
+ x
+ }, warning = function(w) "stopped at the warning")
[1] "stopped at the warning"
> # finally runs whatever happens.
> tryCatch(stop("boom"), error = function(e) conditionMessage(e), finally = cat("finally ran\n"))
finally ran
[1] "boom"
> # conditionCall() gives the call that signalled it.
> tryCatch(log(-1), warning = function(w) deparse(conditionCall(w)))
[1] "log(-1)"
> # try() is the short form for errors: it returns an object of class "try-error".
> res <- try(log("ten"), silent = TRUE)
> class(res)
[1] "try-error"
> inherits(res, "try-error")
[1] TRUE
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 trycatch_session.py
The line after as.numeric("abc") never ran: tryCatch() left the expression at the warning, so its result was the
handler’s “stopped at the warning”. finally runs last whether or not a condition happened, which suits clean-up
that belongs to the caller. conditionMessage(e) and conditionCall(w) read the parts of a condition, here
"boom" and "log(-1)". try(expr, silent = TRUE) is the short form for errors: it returns the value, or an object
of class "try-error" holding the message. Test it with inherits(res, "try-error"), which looks through the whole
class vector, rather than comparing class(res) with ==.
Catching warnings with tryCatch() when the result matters
tryCatch(expr, warning = ...) stops expr at its first warning, so a long computation that warns once returns
only the handler’s value and none of its work. To note a warning and keep the result, use withCallingHandlers(),
the next section.
Checkpoint
Check: Errors, warnings and messages · Recovering with tryCatch() and try()
withCallingHandlers() handles a condition and carries on
withCallingHandlers(as.numeric(amounts), warning = ...) printed “logged: NAs introduced by coercion” and still
returned all four values, 1200 NA NA 980. A calling handler: A handler set up by withCallingHandlers(). It runs where the condition was signalled, and the code carries on afterwards unless the handler leaves or invokes a restart. runs at the point
where the condition was signalled, without leaving the expression, as ?conditions describes: if the handler returns,
R tries the next handler and then carries on. Inside it, invokeRestart("muffleWarning") uses a
restart: A point that code sets up for a handler to jump back to. warning() provides muffleWarning and message() muffleMessage, so a calling handler can silence one and let the code go on. that warning() provides, so the warning counts as dealt with and is not printed.
Compare the path with the previous figure:
The drawing shows the whole scene; its 5 steps are listed below.
Every step as text
- Run the expression. withCallingHandlers() records its warning handler and evaluates as.numeric(amounts) on "1200", "1,500", "n/a" and "980".
- A warning, mid-way. Two of the four cannot be read, so as.numeric() signals "NAs introduced by coercion" while it is still running.
- The handler runs in place. R calls the handler at once, from inside the expression, without leaving it. The handler logs the message.
- Muffle and return. invokeRestart("muffleWarning") tells R that the warning has been dealt with, so it is not printed, and control goes back to where it was signalled.
- The expression finishes. as.numeric() completes and returns 1200 NA NA 980, which becomes the value of withCallingHandlers(). Nothing was abandoned.
The run logs the warning of the four amounts, then uses the same pattern in a reader that converts every column of a data frame:
from session import run, version
version()
# R reads calling_handlers.R as if each line were typed at the console.
run("""
R --vanilla --quiet -f calling_handlers.R
""") Output
# R version 4.6.1 -- "Happy Hop"
$ R --vanilla --quiet -f calling_handlers.R
> # withCallingHandlers() runs the handler where the warning happens, then carries on.
> amounts <- c("1200", "1,500", "n/a", "980")
> withCallingHandlers(
+ as.numeric(amounts),
+ warning = function(w) {
+ message("logged: ", conditionMessage(w))
+ invokeRestart("muffleWarning")
+ }
+ )
logged: NAs introduced by coercion
[1] 1200 NA NA 980
> # A reader that converts every column, records what failed and prints no warning.
> read_numbers <- function(df) {
+ failed <- list()
+ warnings_muffled <- 0
+ for (col in names(df)) {
+ text <- df[[col]]
+ values <- withCallingHandlers(
+ as.numeric(text),
+ warning = function(w) {
+ warnings_muffled <<- warnings_muffled + 1
+ invokeRestart("muffleWarning")
+ }
+ )
+ failed[[col]] <- text[is.na(values) & !is.na(text)]
+ df[[col]] <- values
+ }
+ list(data = df, failed = failed, warnings = warnings_muffled)
+ }
> raw <- data.frame(amount = c("1200", "1,500", "980"), units = c("3", "two", "5"))
> result <- read_numbers(raw)
> result$data
amount units
1 1200 3
2 NA NA
3 980 5
> result$failed
$amount
[1] "1,500"
$units
[1] "two"
> result$warnings
[1] 2
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 calling_handlers_session.py
read_numbers() converted both columns, kept every value that could be read, and returned the text that failed,
"1,500" in amount and "two" in units, with the number of warnings it muffled, 2. Nothing was printed while it
ran, yet nothing was lost: the log says exactly what to fix in the data. Note how the handler counts: it changes
warnings_muffled with <<-, which finds the variable in read_numbers()’s environment, the closure rule of the
lesson on scoping. The help page recommends tryInvokeRestart("muffleWarning") when the warning may come from code
you do not control, because it returns quietly if that restart is missing.
Key idea
tryCatch() abandons the expression and returns the handler’s value; withCallingHandlers() runs the handler
where the condition happened and lets the expression finish, so it is the one to use for logging and counting.
Checkpoint
Check: Logging with withCallingHandlers()
on.exit() cleans up however a function ends
first_line() printed “connection closed” both when it returned “id,amount” and when it stopped with “the first line
is empty”. The help page ?on.exit says the expression it records is run when the current function exits, either
naturally or as the result of an error. So the clean-up is registered right after the resource is opened, before
anything that can fail. Step through both calls:
The drawing shows the whole scene; its 6 steps are listed below.
Every step as text
- Open and register. The function opens a connection and at once registers its clean-up with on.exit(). Nothing is closed yet; the code is kept for the moment the function ends.
- A normal call. For the file with a header, the first line is "id,amount", so the function reaches its last value without an error.
- The clean-up runs. As the function ends, R runs the on.exit code, which closes the connection and prints "connection closed", before the caller receives "id,amount".
- An empty first line. For the second file the first line is "", so stop("the first line is empty") is called while the connection is still open.
- The error path cleans up too. The error leaves the function at once, but R still runs the on.exit code on the way out, so "connection closed" printed before the error message.
- The error goes on. The clean-up does not swallow the error. try() in the caller receives it and prints "the first line is empty"; the connection is closed either way.
The run reads two files, then shows how several on.exit() calls combine:
from session import run, version
version()
# R reads on_exit.R as if each line were typed at the console.
run("""
R --vanilla --quiet -f on_exit.R
""") Output
# R version 4.6.1 -- "Happy Hop"
$ R --vanilla --quiet -f on_exit.R
> # on.exit() runs when the function ends, normally or with an error.
> first_line <- function(path) {
+ con <- file(path, "r")
+ on.exit({
+ close(con)
+ cat("connection closed\n")
+ }, add = TRUE)
+ line <- readLines(con, n = 1)
+ if (line == "") stop("the first line is empty")
+ line
+ }
> path <- tempfile(fileext = ".csv")
> writeLines(c("id,amount", "1,1200"), path)
> first_line(path)
connection closed
[1] "id,amount"
> writeLines(c("", "1,1200"), path)
> try(first_line(path))
connection closed
Error in first_line(path) : the first line is empty
> # Without add = TRUE, a second on.exit() replaces the first.
> replaced <- function() {
+ on.exit(cat("first cleanup\n"))
+ on.exit(cat("second cleanup\n"))
+ "done"
+ }
> replaced()
second cleanup
[1] "done"
> both <- function() {
+ on.exit(cat("first cleanup\n"))
+ on.exit(cat("second cleanup\n"), add = TRUE)
+ "done"
+ }
> both()
first cleanup
second cleanup
[1] "done"
> # after = FALSE puts a cleanup in front of the others.
> in_front <- function() {
+ on.exit(cat("added first\n"))
+ on.exit(cat("added second, runs first\n"), add = TRUE, after = FALSE)
+ invisible()
+ }
> in_front()
added second, runs first
added first
> unlink(path)
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 on_exit_session.py
Without add = TRUE, the second on.exit() replaced the first, so replaced() printed only “second cleanup”. With
add = TRUE both ran, in the order they were added, and after = FALSE put a later one in front. Write
on.exit(..., add = TRUE) every time: then a clean-up added later, in the same function or by an edit next year,
cannot silently cancel one that is already there.
Closing a connection at the end of the function
close(con) on the last line runs only when nothing before it fails. Register it right after file() with
on.exit(close(con), add = TRUE), so an error between the two cannot leave the connection open.
Checkpoint
Check: Clean-up with on.exit()
Classed conditions let a handler choose what it catches
validate_age(c(34, -2, 51, 230)) stopped with an error of class invalid_age that carried the bad rows, 2 and 4, and
their values, -2 and 230. errorCondition(message, class = ..., ...), in base R since R 3.6.0, builds such an error:
the class goes in front of error and condition, and every extra argument becomes a field. A tryCatch() handler
named after the class catches that error and no other, so an unexpected failure still stops the program instead of
being mistaken for bad ages. Step through two errors meeting the same handler:
The drawing shows the whole scene; its 4 steps are listed below.
Every step as text
- A classed error. validate_age() stops with errorCondition(..., class = "invalid_age"), so the condition's class is c("invalid_age", "error", "condition"), and it carries rows and values.
- The class matches. tryCatch() has a handler named invalid_age, one of the condition's classes, so that handler runs. It returns the condition itself, with rows 2 4 and values -2 230.
- An unrelated error. log("ten") stops with a simpleError, whose classes are simpleError, error and condition. None of them is invalid_age.
- It passes through. With no handler for its classes, the error leaves tryCatch() as if it were not there, and try() around it prints "non-numeric argument to mathematical function". Unexpected errors still stop the program.
The run catches the classed error, lets an unrelated one through, and handles a classed message:
from session import run, version
version()
# R reads custom_conditions.R as if each line were typed at the console.
run("""
R --vanilla --quiet -f custom_conditions.R
""") Output
# R version 4.6.1 -- "Happy Hop"
$ R --vanilla --quiet -f custom_conditions.R
> # errorCondition() builds an error with a class and data of your own.
> validate_age <- function(age) {
+ bad <- which(age < 0 | age > 120)
+ if (length(bad) > 0) {
+ stop(errorCondition(
+ paste("invalid age in rows", paste(bad, collapse = ", ")),
+ class = "invalid_age", rows = bad, values = age[bad]
+ ))
+ }
+ age
+ }
> ages <- c(34, -2, 51, 230)
> caught <- tryCatch(validate_age(ages), invalid_age = function(e) e)
> class(caught)
[1] "invalid_age" "error" "condition"
> conditionMessage(caught)
[1] "invalid age in rows 2, 4"
> caught$rows
[1] 2 4
> caught$values
[1] -2 230
> # A handler for one class lets every other error through.
> try(tryCatch(log("ten"), invalid_age = function(e) "never reached"))
Error in log("ten") : non-numeric argument to mathematical function
> # messageCondition() (R 4.6.0) builds a classed message.
> note <- messageCondition("3 rows dropped", class = "dropped_rows")
> class(note)
[1] "dropped_rows" "message" "condition"
> withCallingHandlers(
+ {
+ message(note)
+ "finished"
+ },
+ dropped_rows = function(m) {
+ cat("handled:", conditionMessage(m), "\n")
+ invokeRestart("muffleMessage")
+ }
+ )
handled: 3 rows dropped
[1] "finished"
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 custom_conditions_session.py
The handler received the whole condition, so the caller could read caught$rows and caught$values instead of
parsing the message. log("ten") raised a simpleError, which matched no handler and reached try() unchanged.
R 4.6.0 added messageCondition(), which does the same for messages: the handler for dropped_rows received
“3 rows dropped” and muffled it with invokeRestart("muffleMessage").
Which treatment a condition deserves depends on two questions: whether the computation should go on, and whether you have already decided what the condition means for your data. Answer them for a condition in your own code:
Answer the questions above: the table then marks what fits your case and says why the rest does not.
| Way | Keeps the full result | Leaves a record | Other errors still stop | No noise for users |
|---|---|---|---|---|
| Let it propagate What happens: the caller sees it | Mixed a warning keeps the result; an error ends the call | Good the message reaches the caller and the log | Good nothing is caught | Poor every warning is printed |
| tryCatch() What happens: stops the expression, returns the handler's value | Poor the expression stops at the condition: to_number() gave NA | Mixed only what the handler writes down | Good a handler by class lets other errors through | Good the handler decides what to show |
| withCallingHandlers() What happens: runs the handler, then carries on | Good as.numeric() finished: 1200 NA NA 980 | Good the handler can count or log each one | Good only the named class is handled | Good muffleWarning hides it after logging |
| suppressWarnings() What happens: the warning disappears | Good the computation finishes | Poor no trace of what went wrong | Good errors are not affected | Good nothing printed |
| options(warn = 2) What happens: every warning becomes an error | Poor the first warning ends the computation | Good the warning becomes an error with its message | Good errors stay errors | Poor every warning stops the run |
How the answers decide
- “After the condition, should the computation go on?” Yes, finish it: rules out tryCatch() and options(warn = 2). tryCatch() abandons the expression at the condition, and warn = 2 turns the first warning into an error; neither lets the computation finish.
- “After the condition, should the computation go on?” No, stop or give up: rules out suppressWarnings() and adds a caveat to withCallingHandlers(). Silencing hides the reason for stopping; a calling handler can log, but something else must then stop the run.
- “Have you already decided what the condition means for the data?” No, I need to see it: rules out suppressWarnings(). suppressWarnings() is fine only when you already know what the NAs mean; it leaves no record to decide from.
- “Have you already decided what the condition means for the data?” Yes, and I can say it: adds a caveat to Let it propagate. Once the meaning is decided, repeating the warning to every user adds noise; handle it and record the count instead.
In short: let errors you cannot handle propagate; catch the classes you can handle with tryCatch(); log and count
with withCallingHandlers(); use suppressWarnings() only after you have decided what the warning means; and set
options(warn = 2) in tests, where the help page ?options says warnings are turned into errors.
Checkpoint
Check: Classed conditions and choosing a treatment
Practise: predict, then check
Give each line an answer before you read the run: what it returns, and what it prints on the way.
Your predictions
Predict tryCatch(stop("a"), error = function(e) "b"), a tryCatch() of a warning with a finally that prints
“done”, a withCallingHandlers() that muffles a warning in a block whose last value is “kept going”,
inherits(try(sqrt("4"), silent = TRUE), "try-error"), and a function whose on.exit() prints “bye” before it
returns “hi”. Then type the lines into R.
from session import run, version
version()
# R reads practice.R as if each line were typed at the console.
run("""
R --vanilla --quiet -f practice.R
""") Output
# R version 4.6.1 -- "Happy Hop"
$ R --vanilla --quiet -f practice.R
> tryCatch(stop("a"), error = function(e) "b")
[1] "b"
> tryCatch(warning("w"), warning = function(w) 1, finally = cat("done\n"))
done
[1] 1
> withCallingHandlers({ warning("w"); "kept going" }, warning = function(w) invokeRestart("muffleWarning"))
[1] "kept going"
> r <- try(sqrt("4"), silent = TRUE)
> inherits(r, "try-error")
[1] TRUE
> f <- function() { on.exit(cat("bye\n")); "hi" }
> f()
bye
[1] "hi"
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 practice_session.py
The error handler’s value replaced the error; finally printed “done” before the handler’s 1 was returned; the
calling handler muffled the warning and the block went on to “kept going”; sqrt() of text is an error, so try()
returned a "try-error"; and the clean-up printed “bye” before the function’s value came back.
Then the adaptive questions, your least practised concept first, each with the reason for every choice:
Practice that adapts to you
Practise this lesson
16 questions about 5 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Interview questions
Warm-up: what is the difference between tryCatch() and withCallingHandlers()?
Both establish handlers for classes of conditions, but they do different things when one is signalled. A handler of
tryCatch() is an exiting handler: R abandons the expression at the point of the condition, calls the handler, and
the handler’s value becomes the value of tryCatch(), so any work after the condition is lost. A handler of
withCallingHandlers() is a calling handler: it runs where the condition was signalled, and when it returns, the
expression carries on, so a warning can be logged, counted or muffled with invokeRestart("muffleWarning") while the
computation finishes. Use tryCatch() to recover from an error with a fallback value, and withCallingHandlers() to
observe or record conditions without changing the result.
Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.
-
Mid to senior
A nightly job processes 300 files. One malformed file stops the whole run, and an earlier fix that wrapped everything in tryCatch() made failures silent. Design the error handling so good files are processed, bad ones are reported with their reason, and unexpected errors still stop the job.
-
Fresher to mid
A function opens a database connection and writes a temporary file. When it fails halfway, connections pile up until the database refuses new ones, and temporary files stay behind. How do you make the clean-up reliable, and how do you test that it runs when the function fails?
Key takeaways
stop()ends the call with an error,warning()lets it finish and prints the problem, andmessage()reports progress; each signals a condition whose class vector handlers use to choose.tryCatch()abandons the expression at a matching condition and returns the handler’s value, withfinallyrun last;try()returns an object of class"try-error", tested withinherits().withCallingHandlers()runs its handler where the condition happened and lets the expression finish, so it can log or count warnings and muffle them withinvokeRestart("muffleWarning").on.exit(..., add = TRUE)registers clean-up that runs however the function ends, errors included; withoutadd = TRUE, a lateron.exit()replaces it.errorCondition()andmessageCondition()build conditions of your own class with data attached, so a handler can catch exactly them while other errors still propagate.
Terms in this lesson
- calling handler
- A handler set up by withCallingHandlers(). It runs where the condition was signalled, and the code carries on afterwards unless the handler leaves or invokes a restart.
- condition
- The object R signals to report an error, a warning or a message. It holds a message and the call, and its class vector, such as simpleError, error and condition, is what handlers choose by.
- exiting handler
- A handler set up by tryCatch(). When its condition is signalled, R abandons the expression, runs the handler, and returns the handler's value from tryCatch().
- restart
- A point that code sets up for a handler to jump back to. warning() provides muffleWarning and message() muffleMessage, so a calling handler can silence one and let the code go on.
References
- Condition Handling and Recovery (conditions: tryCatch, withCallingHandlers, errorCondition) (The R Core Team)
- Stop Function Execution (stop) (The R Core Team)
- Warning Messages (warning) (The R Core Team)
- Diagnostic Messages (message) (The R Core Team)
- Function Exit Code (on.exit) (The R Core Team)
- Try an Expression Allowing Error Recovery (try) (The R Core Team)
- Options Settings (options: warn) (The R Core Team)
- R Language Definition: Exception handling (chapter 8) (The R Core Team)
- R News: changes in R 4.6.0 (messageCondition) (The R Core Team)
- R News: changes in R 3.x (R 3.6.0: errorCondition and warningCondition) (The R Core Team)
Report a problem with this lesson
Kept only in this browser. Your Learn progress