ui: 'with-error-handling' does not unwind the stack.

Since a07d5e558b, we've been getting
useless backtraces upon unhandled errors, like this:

  Backtrace:
	     1 (primitive-load "/home/…/bin/guix")
  In guix/ui.scm:
    1953:12  0 (run-guix-command _ . _)

  guix/ui.scm:1953:12: In procedure run-guix-command:
  In procedure struct-vtable: Wrong type argument in position 1 (expecting struct): #f

This change finally gives us real backtraces back.

* guix/ui.scm (guard*): New macro.
(call-with-error-handling): Use it instead of 'guard'.
This commit is contained in:
Ludovic Courtès 2020-07-15 01:11:00 +02:00
parent 8003a5adaf
commit a168c3e4f8
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
1 changed files with 154 additions and 129 deletions

View File

@ -652,6 +652,23 @@ or variants of @code{~a} in the same profile.")
or remove one of them from the profile.")
name1 name2)))))
(cond-expand
(guile-3
;; On Guile 3.0, in 'call-with-error-handling' we need to re-raise. To
;; preserve useful backtraces in case of unhandled errors, we want that to
;; happen before the stack has been unwound, hence 'guard*'.
(define-syntax-rule (guard* (var clauses ...) exp ...)
"This variant of SRFI-34 'guard' does not unwind the stack before
evaluating the tests and bodies of CLAUSES."
(with-exception-handler
(lambda (var)
(cond clauses ... (else (raise var))))
(lambda () exp ...)
#:unwind? #f)))
(else
(define-syntax-rule (guard* (var clauses ...) exp ...)
(guard (var clauses ...) exp ...))))
(define (call-with-error-handling thunk)
"Call THUNK within a user-friendly error handler."
(define (port-filename* port)
@ -660,7 +677,7 @@ or remove one of them from the profile.")
(and (not (port-closed? port))
(port-filename port)))
(guard (c ((package-input-error? c)
(guard* (c ((package-input-error? c)
(let* ((package (package-error-package c))
(input (package-error-invalid-input c))
(location (package-location package))
@ -781,6 +798,10 @@ directories:~{ ~a~}~%")
;; compound and include a '&message'. However, that message only
;; contains the format string. Thus, special-case it here to
;; avoid displaying a bare format string.
;;
;; Furthermore, use of 'guard*' ensures that the stack has not
;; been unwound when we re-raise, since that would otherwise show
;; useless backtraces.
((cond-expand
(guile-3
((exception-predicate &exception-with-kind-and-args) c))
@ -1993,4 +2014,8 @@ and signal handling have already been set up."
(initialize-guix)
(apply run-guix args))
;;; Local Variables:
;;; eval: (put 'guard* 'scheme-indent-function 2)
;;; End:
;;; ui.scm ends here