sigildocs

Exceptions

Error handling with guard, raise, and exception types.

Note: Exception handling requires (import (sigil error)).

guard

Handle exceptions with pattern-like clauses. The primary way to catch errors.

(import (sigil error))

(guard (err
        ((type-error? err)
         (display "Type error: ")
         (display (exception-message err))
         #f)
        ((error? err)
         (display "Error occurred")
         #f)
        (else
         (raise err)))  ; Re-raise if unhandled
  (risky-operation))

Syntax

(guard (variable
        (test expression ...)
        (test expression ...)
        (else expression ...))
  body ...)

Each clause tests the caught exception. If a test succeeds, its expressions are evaluated and the result returned. The else clause catches anything.

Without else

If no clause matches and there's no else, the exception propagates.

(guard (e ((eq? (exception-kind e) 'expected) 'handled))
  (raise (make-exception 'unexpected "oops" '())))
; Exception propagates (not caught)

raise

Signal an exception. Transfers control to the nearest handler.

(raise (make-exception 'my-error "something went wrong" '()))

error

Convenient way to signal an error with a formatted message.

(error "Something went wrong")
(error "Invalid argument: ~a" x)
(error "Expected ~a, got ~a" expected actual)

The message uses format-style placeholders:

  • ~a - Display representation
  • ~s - Write representation (quoted strings)

Exception Types

Sigil provides typed exceptions via (sigil error):

(import (sigil error))

;; Type predicates
(exception? e)     ; Any exception
(error? e)         ; General error
(type-error? e)    ; Type mismatch
(range-error? e)   ; Value out of range
(arity-error? e)   ; Wrong argument count

;; Constructors
(make-exception 'kind "message" irritants)
(make-error "message")
(make-type-error "message" expected-type actual-value)
(make-range-error "message" value min max)
(make-arity-error "message" expected-count actual-count)

Exception Fields

(exception-kind e)       ; Symbol identifying error type
(exception-message e)    ; Human-readable message
(exception-irritants e)  ; Related values (list)
(exception-stack-trace e) ; Stack trace if available

make-exception

Create a custom exception.

(make-exception 'not-found "Resource not found" (list path))

Arguments:

  1. Kind (symbol) - identifies the exception type
  2. Message (string) - human-readable description
  3. Irritants (list) - related values for debugging

Common Patterns

Safe Operations

(define (safe-divide a b)
  (guard (e (else #f))
    (/ a b)))

(safe-divide 10 2)   ; => 5
(safe-divide 10 0)   ; => #f

Default on Error

(define (read-config-or-default path)
  (guard (e ((error? e) (default-config)))
    (read-config path)))

Re-raise After Logging

(define (with-error-logging thunk)
  (guard (e (else
             (display "Error: ")
             (display (exception-message e))
             (newline)
             (raise e)))  ; Re-raise after logging
    (thunk)))

Stack Traces

When an unhandled exception reaches the REPL, Sigil prints a stack trace showing where the error occurred.

In code, access via (exception-stack-trace e) when available.

with-exception-handler

Low-level handler installation. Rarely needed directly—prefer guard.

(with-exception-handler
  (lambda (e)
    (display "caught!")
    (raise e))  ; Must re-raise or return
  (lambda ()
    (risky-operation)))

The handler must either:

  • Raise the exception (or a different one)
  • Return a value (only for continuable exceptions)