Next: Lazy Catch, Previous: Catch, Up: Exceptions
It's sometimes useful to be able to intercept an exception that is being
thrown, but without changing where in the dynamic context that exception
will eventually be caught. This could be to clean up some related state
or to pass information about the exception to a debugger, for example.
The with-throw-handler
procedure provides a way to do this.
Add handler to the dynamic context as a throw handler for key key, then invoke thunk.
The above
scm_with_throw_handler
takes Scheme procedures as body (thunk) and handler arguments.scm_c_with_throw_handler
is an equivalent taking C functions. Seescm_c_catch
(see Catch) for a description of the parameters, the behaviour however of course followswith-throw-handler
.
If thunk throws an exception, Guile handles that exception by
invoking the innermost catch
or throw handler whose key matches
that of the exception. When the innermost thing is a throw handler,
Guile calls the specified handler procedure using (apply
handler key args)
. The handler procedure may either return
normally or exit non-locally. If it returns normally, Guile passes the
exception on to the next innermost catch
or throw handler. If it
exits non-locally, that exit determines the continuation.
The behaviour of a throw handler is very similar to that of a
catch
expression's optional pre-unwind handler. In particular, a
throw handler's handler procedure is invoked in the exact dynamic
context of the throw
expression, just as a pre-unwind handler is.
with-throw-handler
may be seen as a half-catch
: it does
everything that a catch
would do until the point where
catch
would start unwinding the stack and dynamic context, but
then it rethrows to the next innermost catch
or throw handler
instead.