[plt-scheme] exception handling

From: Dave Griffiths (dave at pawfal.org)
Date: Tue Jan 20 09:01:21 EST 2009

On Tue, 2009-01-20 at 05:51 -0700, Matthew Flatt wrote:
> At Tue, 20 Jan 2009 12:31:12 +0000, Dave Griffiths wrote:
> > A quick question about exception handling. I'd like to run a thunk in a
> > context where I can capture the error and do something with it in code -
> > i.e. keep the program running after the error has occurred. For example
> > something like this:
> > 
> > (define error-happened #f)
> > 
> > (define (err n)
> >   (set! error-happened #t))
> > 
> > (call-with-exception-handler err (lambda () (modulo 0 1 2)))
> > 
> > (when error-happened
> >   (do-something))
> > 
> > However, the value of (err) is passed to the uncaught exception handler,
> > which in turn stops evaluation. I certainly don't want to turn off the
> > normal exception handling globally, so I'm guessing I can use
> > (with-handlers) but I'm not sure how.
> 
> An exception handler has to escape out of the expression that raised
> the exception. And, to escape, you have to create a place to escape to.
> 
> The most primitive way to do that is to set a prompt and abort to it:
> 
>  (define recover-tag (make-continuation-prompt-tag))
> 
>  (define (err n)
>    (set! error-happened #t)
>    (abort-current-continuation recover-tag 10))
> 
>  (define (call-as-recoverable thunk)
>    (call-with-continuation-prompt
>     thunk
>     recover-tag
>     (lambda (v) v)))
> 
>  (call-with-exception-handler err (lambda () 
>                                     (+ (call-as-recoverable
>                                         (lambda () (modulo 0 1 2)))
>                                        5)))
> 
> That's pretty much what `with-handlers' does:
> 
>  (define (err n)
>    (set! error-happened #t)
>    10) ; just return a value, because `with-handlers' handles abort
> 
>  (+ (with-handlers ([(lambda (x) #t) err])
>       (modulo 0 1 2))
>      5)
> 
> 
> Some Scheme/Lisp systems effectively put a prompt at every call to a
> primitive function, so that an exception handler can recover from any
> exception that was raised by a primitive by aborting to the call. PLT
> Scheme doesn't support that, though.

Thanks! That works perfectly for me. 

The ability to do this makes livecoding much more forgiving in certain situations :)

Maybe more detailed questions on this at a later date...

cheers,

dave



Posted on the users mailing list.