Handling Errors Deterministically

Use `with-exception-handler` for procedural handling and `guard` for condition-style matching over catchable error objects.

See it run

LISPEX
(guard (e ((error-object? e) (error-object-message e))) (error "bad input"))

Observed result

OUTPUT
"bad input"

Walk through the pattern

  1. Raise a guest error. (error "bad input") creates a catchable error object with a stable message.
  2. Match structured data. guard tests error-object? rather than parsing rendered text.
  3. Return a recovery value. The selected clause extracts the message, so the whole form evaluates to "bad input".

How to reason about it

  • raise-continuable returns the handler result to the raise site; non-continuable raise cannot return normally.
  • Inspect error objects with the documented predicates/accessors rather than parsing rendered diagnostic text.
  • When no guard clause matches, the original fault is reraised unchanged.

Check yourself

What happens if no guard clause matches the error object?

Answer

The original error is raised again unchanged. A missing match is not converted into a generic success value.

A common mistake

ResourceLimit is not catchable, and host crashes are never converted into friendly guest errors.

Keep going

Diagnostics explains phases and codes. Decision Rules shows how to reject invalid input before returning a business decision.

Diagnostics · Decision rules