Skip to main content

error

error Function

Syntax:

error datum &rest arguments →

Arguments and Values:

datum, argumentsdesignators for a condition of default type simple-error.

Description:

error effectively invokes signal on the denoted condition.

If the condition is not handled, (invoke-debugger condition) is done. As a consequence of calling invoke-debugger, error cannot directly return; the only exit from error can come by non-local transfer of control in a handler or by use of an interactive debugging command.

Examples:

(defun factorial (x) 
(cond ((or (not (typep x ’integer)) (minusp x))
(error "~S is not a valid argument to FACTORIAL." x))
((zerop x) 1)


**error**
(t (\* x (factorial (- x 1))))))
→ FACTORIAL
(factorial 20)
2432902008176640000
(factorial -1)
▷ Error: -1 is not a valid argument to FACTORIAL.
▷ To continue, type :CONTINUE followed by an option number:
▷ 1: Return to Lisp Toplevel.
▷ Debug>
(setq a ’fred)
→ FRED
(if (numberp a) (1+ a) (error "~S is not a number." A))
▷ Error: FRED is not a number.
▷ To continue, type :CONTINUE followed by an option number:
▷ 1: Return to Lisp Toplevel.
▷ Debug> :Continue 1
▷ Return to Lisp Toplevel.
(define-condition not-a-number (error)
((argument :reader not-a-number-argument :initarg :argument))
(:report (lambda (condition stream)
(format stream "~S is not a number."
(not-a-number-argument condition)))))
→ NOT-A-NUMBER
(if (numberp a) (1+ a) (error ’not-a-number :argument a))
▷ Error: FRED is not a number.
▷ To continue, type :CONTINUE followed by an option number:
▷ 1: Return to Lisp Toplevel.
▷ Debug> :Continue 1
▷ Return to Lisp Toplevel.

Side Effects:

Handlers for the specified condition, if any, are invoked and might have side effects. Program execution might stop, and the debugger might be entered.

Affected By:

Existing handler bindings.

*break-on-signals*

Signals an error of type type-error if datum and arguments are not designators for a condition.

See Also:

cerror, signal, format, ignore-errors, *break-on-signals*, handler-bind, Section 9.1 (Condition

System Concepts)

Notes:

Some implementations may provide debugger commands for interactively returning from individual stack frames. However, it should be possible for the programmer to feel confident about writing code like:

(defun wargames:no-win-scenario ()

(if (error "pushing the button would be stupid."))

(push-the-button))

In this scenario, there should be no chance that error will return and the button will get pushed.

While the meaning of this program is clear and it might be proven ‘safe’ by a formal theorem prover, such a proof is no guarantee that the program is safe to execute. Compilers have been known to have bugs, computers to have signal glitches, and human beings to manually intervene in ways that are not always possible to predict. Those kinds of errors, while beyond the scope of the condition system to formally model, are not beyond the scope of things that should seriously be considered when writing code that could have the kinds of sweeping effects hinted at by this example.

Expanded Reference: error

Signaling an Error with a Format String

The simplest usage of error passes a format control string and optional arguments. This creates a simple-error condition and enters the debugger if unhandled.

(handler-case
(error "Expected a number, got: ~S" 'foo)
(simple-error (c)
(format nil "Caught: ~A" c)))

=> "Caught: Expected a number, got: FOO"

Error Never Returns Normally

error is guaranteed never to return normally. Control can only leave error via a non-local transfer (e.g., a handler or restart).

(handler-case
(progn
(error "fatal problem")
:unreachable)
(error () :handled))

=> :HANDLED

Signaling a Condition Type by Name

Instead of a string, you can pass a condition type symbol along with initargs. This creates a condition of that type.

(handler-case
(error 'type-error :datum "hello" :expected-type 'integer)
(type-error (c)
(format nil "~S is not of type ~S"
(type-error-datum c)
(type-error-expected-type c))))

=> "\"hello\" is not of type INTEGER"

Signaling a Pre-made Condition Object

You can also pass an already-constructed condition object to error.

(let ((c (make-condition 'simple-error
:format-control "Disk ~A is full"
:format-arguments '("C"))))
(handler-case (error c)
(simple-error (caught)
(format nil "Caught: ~A" caught))))

=> "Caught: Disk C is full"

Using Error in a Validation Function

A typical pattern is to signal an error when input validation fails.

(defun factorial (n)
(unless (and (integerp n) (>= n 0))
(error "~S is not a non-negative integer" n))
(if (zerop n) 1 (* n (factorial (1- n)))))

(factorial 5)

=> 120
(handler-case (factorial -3)
(simple-error (c)
(format nil "~A" c)))

=> "-3 is not a non-negative integer"