Node:Catch, Next:, Previous:Exception Terminology, Up:Exceptions



26.7.2 Catching Exceptions

catch is used to set up a target for a possible non-local jump. The arguments of a catch expression are a key, which restricts the set of exceptions to which this catch applies, a thunk that specifies the normal case code -- i.e. what should happen if no exceptions are thrown -- and a handler procedure that says what to do if an exception is thrown. Note that if the normal case thunk executes normally, which means without throwing any exceptions, the handler procedure is not executed at all.

When an exception is thrown using the throw primitive, the first argument of the throw is a symbol that indicates the type of the exception. For example, Guile throws an exception using the symbol numerical-overflow to indicate numerical overflow errors such as division by zero:

(/ 1 0)
=>
ABORT: (numerical-overflow)

The key argument in a catch expression corresponds to this symbol. key may be a specific symbol, such as numerical-overflow, in which case the catch applies specifically to exceptions of that type; or it may be #t, which means that the catch applies to all exceptions, irrespective of their type.

The second argument of a catch expression should be a thunk (i.e. a procedure that accepts no arguments) that specifies the normal case code. The catch is active for the execution of this thunk, including any code called directly or indirectly by the thunk's body. Evaluation of the catch expression activates the catch and then calls this thunk.

The third argument of a catch expression is a handler procedure. If an exception is thrown, this procedure is called with exactly the arguments specified by the throw. Therefore, the handler procedure must be designed to accept a number of arguments that corresponds to the number of arguments in all throw expressions that can be caught by this catch.

catch key thunk handler Scheme Procedure
scm_catch (key, thunk, handler) C Function
Invoke thunk in the dynamic context of handler for exceptions matching key. If thunk throws to the symbol key, then handler is invoked this way:
(handler key args ...)

key is a symbol or #t.

thunk takes no arguments. If thunk returns normally, that is the return value of catch.

Handler is invoked outside the scope of its own catch. If handler again throws to the same key, a new handler from further up the call chain is invoked.

If the key is #t, then a throw to any symbol will match this call to catch.

If the handler procedure needs to match a variety of throw expressions with varying numbers of arguments, you should write it like this:

(lambda (key . args)
  ...)

The key argument is guaranteed always to be present, because a throw without a key is not valid. The number and interpretation of the args varies from one type of exception to another, but should be specified by the documentation for each exception type.

Note that, once the handler procedure is invoked, the catch that led to the handler procedure being called is no longer active. Therefore, if the handler procedure itself throws an exception, that exception can only be caught by another active catch higher up the call stack, if there is one.