Next: , Previous: Lazy Catch, Up: Exceptions


5.11.7.5 Throwing Exceptions

The throw primitive is used to throw an exception. One argument, the key, is mandatory, and must be a symbol; it indicates the type of exception that is being thrown. Following the key, throw accepts any number of additional arguments, whose meaning depends on the exception type. The documentation for each possible type of exception should specify the additional arguments that are expected for that kind of exception.

— Scheme Procedure: throw key . args
— C Function: scm_throw (key, args)

Invoke the catch form matching key, passing args to the handler.

key is a symbol. It will match catches of the same symbol or of #t.

If there is no handler at all, Guile prints an error and then exits.

When an exception is thrown, it will be caught by the innermost catch or throw handler that applies to the type of the thrown exception; in other words, whose key is either #t or the same symbol as that used in the throw expression. Once Guile has identified the appropriate catch or throw handler, it handles the exception by applying the relevant handler procedure(s) to the arguments of the throw.

If there is no appropriate catch or throw handler for a thrown exception, Guile prints an error to the current error port indicating an uncaught exception, and then exits. In practice, it is quite difficult to observe this behaviour, because Guile when used interactively installs a top level catch handler that will catch all exceptions and print an appropriate error message without exiting. For example, this is what happens if you try to throw an unhandled exception in the standard Guile REPL; note that Guile's command loop continues after the error message:

     guile> (throw 'badex)
     <unnamed port>:3:1: In procedure gsubr-apply ...
     <unnamed port>:3:1: unhandled-exception: badex
     ABORT: (misc-error)
     guile>

The default uncaught exception behaviour can be observed by evaluating a throw expression from the shell command line:

     $ guile -c "(begin (throw 'badex) (display \"here\\n\"))"
     guile: uncaught throw to badex: ()
     $

That Guile exits immediately following the uncaught exception is shown by the absence of any output from the display expression, because Guile never gets to the point of evaluating that expression.