Hello,

I am trying to print a stack trace when I handle an exception from a
procedure my code is invoking.  I put together following code:

--8<---------------cut here---------------start------------->8---
(define-module (exc)
  #:use-module (ice-9 exceptions))

(define-exception-type &stack &error
  make-exception-with-stack exception-with-stack?
  (stack exception-with-stack-stack))

(define (foo)
  (1+ (bar)))

(define (bar)
  (1+ (baz)))

(define* (baz #:optional val)
  (if val
      val
      (raise-exception
       (make-exception (make-error)
                       (make-exception-with-message "Message.")
                       (make-exception-with-irritants '(1 2 3))))))

(define-public (main _)
  (with-exception-handler (λ (exc)
                            (print-exception (current-error-port)
                                             #f
                                             '%exception
                                             (list exc))
                            (display-backtrace (exception-with-stack-stack exc)
                                               (current-error-port)
                                               0))
    (λ ()
      (with-exception-handler
          (λ (exc)
            (let ((stack (make-stack #t)))
              (raise-exception
               (make-exception exc
                               (make-exception-with-stack stack)))))
        (λ ()
          (foo))))
    #:unwind? #t))
--8<---------------cut here---------------end--------------->8---

When I run the script, I get the following output:

--8<---------------cut here---------------start------------->8---
$ GUILE_AUTO_COMPILE=0 guild compile -W3 -O0 -o /tmp/exc/exc.go /tmp/exc/exc.scm
/tmp/exc/exc.scm:4:0: warning: possibly unused local top-level variable 
`exception-with-stack?'
wrote `/tmp/exc/exc.go'
$ GUILE_AUTO_COMPILE=0 guile -L /tmp/exc -C /tmp/exc -e '(exc)' -c ''
ERROR:
  1. &error
  2. &message: "Message."
  3. &irritants: (1 2 3)
  4. &stack: #<stack 7f22e2cbad40>
In ice-9/boot-9.scm:
  1752:10 10 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _)
In unknown file:
           9 (apply-smob/0 #<thunk 7f22e2ca0300>)
In ice-9/boot-9.scm:
    724:2  8 (call-with-prompt ("prompt") #<procedure 7f22e2cb1200 at 
ice-9/eval.scm:330:…> …)
In ice-9/eval.scm:
    619:8  7 (_ #(#(#<directory (guile-user) 7f22e2ca3c80>)))
In ice-9/boot-9.scm:
  1747:15  6 (with-exception-handler #<procedure 7f22d9807978 at 
/tmp/exc/exc.scm:23:26 (…> …)
  1752:10  5 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _)
In /tmp/exc/exc.scm:
      9:6  4 (foo)
     12:6  3 (bar)
In ice-9/boot-9.scm:
  1685:16  2 (raise-exception _ #:continuable? _)
In /tmp/exc/exc.scm:
    34:25  1 (_ #<&compound-exception components: (#<&error> #<&message 
message: "Message.…>)
In unknown file:
           0 (make-stack #t)
--8<---------------cut here---------------end--------------->8---

I have few question I hope someone here will be able to help me with.

1. Is the double with-exception-handler

  (with-exception-handler print-exc
    (λ ()
      (with-exception-handler capture-stack-and-re-raise
        thunk))
    #:unwind? #t)

the best solution, or is there some more elegant way?

2. The stack print above does not show the `baz' procedure at all.  Am I
doing something wrong?  Should the stack capture be done in a different
manner?

3. How can I actually print the stack using the print-exception?  The
procedure is described as "an extensible exception printer", but

  (set-exception-printer! &stack (λ (exc) (pk exc)))

did not seem to actually do anything.  So how can I provide custom
printers for my exception type, how can I extend the printer?

4. Am I just reinventing already made wheel?  Is there something
built-in I should be using instead?

Happy Christmas,
Tomas

-- 
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.

Attachment: signature.asc
Description: PGP signature

Reply via email to