[gambit-list] Displaying Exceptions: internal gambit function I can use?

Christian christian at pflanze.mine.nu
Mon Nov 13 19:00:42 EST 2006


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 , at 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))))



More information about the Gambit-list mailing list