It looks like you have `call-with-exception-handler' right, but not `with-handlers'.
The exception handler installed by `with-handlers' needs to escape to the context of the `with-handlers' form before finding whether any handlers apply. In other words, `with-handlers' combines a prompt (using a generated tag) with a continuation mark. If no handler is found, the exception should be re-raised using `raise'. At Fri, 3 Sep 2010 14:05:43 -0400, Danny Yoo wrote: > I'm about to try replicating Racket's exception system in WeScheme, so > I want to make sure I understood the model beforehand. Here's my > understanding of the system, and if people can correct me, I'd greatly > appreciate it! > > > * Exception handlers are managed by keeping a chain of these handlers > within the continuation marks. A form like with-handlers effectively > extends the chain within its dynamic extent. There's a designated > continuation-marks key used to keep track of exception handlers. This > key is internal and otherwise inaccessible to the outside world. Let > me call this key "K" for the moment. If it were possible to get at K, > then hypothetically I would be able to observe it by doing something > like this: > > (begin > (printf "Before: ~s~n" (continuation-mark-set->list > (current-continuation-marks) K)) > (with-handlers ([exn void]) > (printf "Within: ~s~n" (continuation-mark-set->list > (current-continuation-marks) K))) > > > * Whenever an exception happens, the runtime immediately grabs the > current continuation marks and extracts the chain of exception > handlers associated to K. It then walks the chain. Each element in > the chain is responsible for returning the exception up the chain. If > an exception handler knows what to do with an exception, and wants to > interrupt the chain, then it is supposed to call the > error-escape-handler to stop the rest of the computation. > > > I looked at the exceptions proposal [Friedman95 > http://www.cs.indiana.edu/scheme-repository/doc.proposals.exceptions.html > ]. I see that the proposal defines a current-exception-handlers, but > I don't see such a function in Racket. I assume that the only way to > adjust the current exception handler is through > call-with-exception-handler. > > > > If I wanted to simulate the exception-handling mechanism, it might > look something like this: > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ;;;;;;;;;;;;;;;;;;;;;;;;;; > #lang racket > > (define K (cons "my-distinguished" > "exception key!")) > > > (define-syntax (simulate stx) > (syntax-case stx () > [(_ body ...) > (syntax/loc stx > (call-with-exception-handler my-exception-handler > (lambda () > body ...)))])) > > > (define (my-uncaught-exception-handler exn) > (printf "I am the uncaught exception handler, seeing ~s~n" exn) > (abort-current-continuation (default-continuation-prompt-tag) void)) > > > (define (my-exception-handler exn) > (printf "my-exception-handler\n") > (let ([handlers > (continuation-mark-set->list (current-continuation-marks) > K)]) > (printf "I see the following handlers: ~s\n" handlers) > (let ([exn > (foldl (lambda (a-handler exn) > (a-handler exn)) > exn > handlers)]) > > ;; At this point, calls the uncaught-exception-handler if none of the > ;; handlers will support us. > (printf "Uncaught exception handler kicking in.\n") > (my-uncaught-exception-handler exn) > (printf "I should never see this!\n")))) > > > (define-syntax (my-with-handlers stx) > (syntax-case stx () > [(_ ([exn-test? on-exn] > ...) > body ...) > (syntax/loc stx > ;; NOTE: I need to make sure the with-continuation-mark is not > in tail position, > ;; or else my t2 shows that an exception handlers has been > replaced, rather than nested. > (let ([result > (with-continuation-mark K (lambda (exn) > (cond > [(exn-test? exn) > (on-exn exn) > (abort-current-continuation > > (default-continuation-prompt-tag) > void)] > ... > [else > exn])) > > (begin body ...))]) > result))])) > > > ;; test1: see that I can catch an exception > (define (t1) > (simulate (my-with-handlers ((exn:fail? (lambda (exn) > (printf "Oh! I see ~s~n" exn)))) > (printf "Starting up~n") > (/ 1 0)))) > > ;; test2: see that I can observe the nesting, and also fire off the > uncaught exception handler > (define (t2) > (simulate (my-with-handlers () > (printf "Starting up~n") > (my-with-handlers () > (/ 1 0))))) > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > _________________________________________________ > For list-related administrative tasks: > http://lists.racket-lang.org/listinfo/users _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users