Check your understanding

Quiz

You have finished the defensive-code section: signalling with stop, warning and message, recovering with tryCatch, validating inputs with stopifnot, and finding bugs with traceback and browser. This short quiz checks what stuck. Pick an answer to continue; you can retry until it clicks. The last two steps are live R, run them and tinker.

Question 1 of 8

Three voices, three severities

Your function meets input it cannot use at all. Which signal abandons the rest of the work?

Right. stop() is for "I cannot continue"; warning() flags a concern but carries on, and message() is just a note.
print() shows a value; it does not signal a problem.
Question 2 of 8

What tryCatch recovers

You wrap a risky call as tryCatch(risky(), error = function(e) 0). The call raises an error. What does the whole expression return?

Right. When the expression errors, the matching handler runs instead and its return value becomes the value of tryCatch.
Unless your handler returns the message, you get whatever the handler returns, here 0.
Question 3 of 8

Prevent versus recover

You want a function to refuse plainly invalid input immediately, before doing any work, with a clear message. Which tool fits?

Right. stopifnot() checks the inputs first and raises a clear, named error the moment a rule breaks.
A message does not stop the bad input from being used.
Question 4 of 8

When finally runs

A tryCatch() has a finally = block. When does that block run?

Right. finally is for cleanup you cannot skip, like closing a file, so it runs on both paths.
It runs every time the tryCatch completes.
Question 5 of 8

After an error, where did it come from

An error fired deep inside nested function calls. Which tool shows you the chain of calls that led to it?

Right. traceback() shows the path of calls, so you can see which function actually raised the error.
Loading a package has nothing to do with tracing an error.
Question 6 of 8

Freezing a function to look inside

You want to pause a running function partway through and inspect its variables interactively. Which tool does that?

Right. browser() halts execution at that line and lets you look at the local variables and step through.
Printing helps a little, but browser() is the tool built for interactive inspection.
Run it: recover with tryCatch

tryCatch in live R

Make a square-root helper that returns NA instead of crashing on bad input. Run it on a good value and a bad one.

RInteractive R
safe_sqrt <- function(x) { tryCatch(sqrt(x), error = function(e) NA_real_) } safe_sqrt(16) # works, returns 4 safe_sqrt("oops") # caught, returns NA instead of stopping

  

The bad call raised an error, but tryCatch caught it and handed back NA, so the program kept going.

Run it: validate with stopifnot

stopifnot in live R

Guard a function's input up front, then call it on a value that passes. Run it, then change 25 to a negative number to see the named error.

RInteractive R
fee <- function(days) { stopifnot("days must be 0 or more" = days >= 0) days * 0.25 } fee(25) # passes the check, returns the fee

  

When the check passes, stopifnot() is silent and the function continues; the instant a condition is false, it stops with your named message.

Section complete

Well done. You can pick the right signal among stop, warning and message, recover from an error with tryCatch, validate inputs up front with stopifnot, rely on finally for cleanup, trace an error's origin with traceback(), and freeze a function with browser(). Next section: a reproducible workflow and the modern R toolchain.