Hey guys,
I'd like to re-use part of the Gambit exception handler, specifically the part that displays the details of the current exception.
I'd also like to hook into the display routine to specialize the display of my own custom exceptions, but this is mostly secondary.
Cheers
Jonathan Arkell jonnay@jonnay.net
Afficher les réponses par date
At 0:33 Uhr -0700 13.11.2006, Jonathan Arkell wrote:
Hey guys,
I'd like to re-use part of the Gambit exception handler, specifically the part that displays the details of the current exception.
See below for some code I'm using (will be in a module called |cj-exception| when released with chjmodule). (Of course I'm never saying that the internal functions I'm suggesting to use represent any officially guaranteed stable interface.)
(BTW I suggest you read the mailing list archive, you can find some tips there like the one to use ##cmd-b)
I'd also like to hook into the display routine to specialize the display of my own custom exceptions, but this is mostly secondary.
(I havend looked into this yet, maybe look at the Gambit sources, perhaps in lib/_repl.scm)
Christian.
;; stuff I'm importing from other libraries (I hope I haven't forgot anything) (define-macro (& first . rest) `(lambda() ,first ,@rest)) (define warn println);;well not really the same thing ;; /library stuff
(define-type exception/continuation id: 4bad9e82-f84c-4ae4-9ba7-c8964bf3dffc exception continuation)
(define (to-port-or-string maybe-port fn) (if maybe-port (fn maybe-port) (with-output-to-string "" (& (fn (current-output-port))))))
(define (exception/continuation-contextline e #!optional port) (to-port-or-string port (lambda (port) (##cmd-y 0 (exception/continuation-continuation e) #f port))))
(define (exception/continuation-contextlines e #!optional port) (to-port-or-string port (lambda (port) (##cmd-b 0 (exception/continuation-continuation e) port))))
(define (exception/continuation-message-in-context e #!optional port) (to-port-or-string port (lambda (port) (##display-exception-in-context (exception/continuation-exception e) (exception/continuation-continuation e) port))))
(define (exception/continuation-procedure e) (##exception->procedure (exception/continuation-exception e) (exception/continuation-continuation e)))
(define (exception/continuation-locat e) (##exception->locat (exception/continuation-exception e) (exception/continuation-continuation e)))
(define (exception/continuation-text e #!optional port) (to-port-or-string port (lambda (port) (##display-exception (exception/continuation-exception e) port))))
(define (repl-within-exception/continuation e) (if (exception/continuation? e) (##repl-within (exception/continuation-continuation e) "repl-within-exception/continuation" ;; dunno where this would show up, never seen it ) (error " not a exception/continuation:" e)))
;; serialisation: (note: not perfect yet!)
(define-type exception/continuation&string id: d3a6b590-3d09-48e2-99e3-01e076126796 exception/continuation string) ;; (btw use type extensions instead?)
(define (exception/continuation->serialisation-object e) (make-exception/continuation&string e (exception/continuation-contextlines e)))
(define (exception/continuation->u8vector e);; (name should maybe be variant with a &?) (object->u8vector (exception/continuation->serialisation-object e) (lambda (obj) (cond ((mutex? obj) (warn "ignoring mutex:" obj) #f) ((##foreign? obj) (warn "ignoring foreign object:" obj) #f) ((condition-variable? obj) (warn "ignoring condition-variable:" obj) #f) (else obj))))) ;;note: replacing objects with #f may lead to problems, of course (I haven't run into any so far, tough)
(define (u8vector->backtrace vec) ;;; (bad name) (exception/continuation&string-string (u8vector->object vec)))
(define (with-exception/continuation-catcher handler th) (##continuation-capture;; no 'with winding' ? ~clearly not (lambda (cont) (with-exception-handler (lambda (e) (##continuation-capture (lambda (c) (##continuation-graft-with-winding cont handler (make-exception/continuation e c))))) th))))
Christian, thanks a lot for the pointers, and even better, that snippet of code.
I found waht I was looking for actually (##display-exception exc port) does the job quite nicely. Adding custom display routines to that should be relatively straightforward.
Jonathan Arkell jonnay@jonnay.net