diff --git a/host/chez/records.ss b/host/chez/records.ss index eb21e91..3a3d880 100644 --- a/host/chez/records.ss +++ b/host/chez/records.ss @@ -255,10 +255,21 @@ ;; &message text plus any &irritants, or display-condition output as a fallback. (define (condition->message-string c) (if (message-condition? c) - (let ((m (condition-message c)) - (irr (if (irritants-condition? c) (condition-irritants c) '()))) - (let loop ((xs irr) (acc m)) - (if (null? xs) acc (loop (cdr xs) (string-append acc " " (jolt-pr-str (car xs))))))) + (let* ((m (condition-message c)) + (irr (if (irritants-condition? c) (condition-irritants c) '())) + (append-irr (lambda () + (let loop ((xs irr) (acc m)) + (if (null? xs) acc + (loop (cdr xs) (string-append acc " " (jolt-pr-str (car xs))))))))) + ;; some Chez conditions (open-input-file etc.) carry a format-template + ;; message ("failed for ~a: ~(~a~)") whose irritants fill the directives; + ;; format it in. Fall back to appending the irritants if that fails. + (if (and (string? m) (let scan ((i 0)) + (cond ((>= i (string-length m)) #f) + ((char=? (string-ref m i) #\~) #t) + (else (scan (+ i 1)))))) + (guard (e (#t (append-irr))) (apply format m irr)) + (append-irr))) (with-output-to-string (lambda () (display-condition c))))) ;; expose a Chez condition's message to Clojure (ex-message returns nil for raw ;; host conditions): the nREPL eval handler surfaces it instead of an opaque diff --git a/stdlib/clojure/test.clj b/stdlib/clojure/test.clj index 46d722e..789c350 100644 --- a/stdlib/clojure/test.clj +++ b/stdlib/clojure/test.clj @@ -46,6 +46,14 @@ (defn n-error [] (:error @counters)) (defn failures [] (:fails @counters)) +;; Message of a thrown value: ex-info's message, else a raw host condition's text +;; (ex-message is nil for those), else its printed form — so a crash is never +;; reported with a blank message. +(defn err-text [e] + (or (ex-message e) + (jolt.host/condition-message e) + (str e))) + ;; clojure.test/report multimethod — present so suites that add reporting ;; methods (defmethod clojure.test/report :begin-test-var ...) load. The runner ;; below does its own console output and doesn't dispatch through it. @@ -110,7 +118,7 @@ (clojure.test/inc-pass!) (clojure.test/fail! (str (pr-str '~form) (when ~msg (str " — " ~msg))))) (catch Throwable e# - (clojure.test/err! (str (pr-str '~form) " threw: " (clojure.core/ex-message e#)))))))) + (clojure.test/err! (str (pr-str '~form) " threw: " (clojure.test/err-text e#)))))))) (defmacro testing [s & body] `(do @@ -152,7 +160,7 @@ (try ((:fn t)) (catch Throwable e - (err! (str (:name t) " crashed: " (clojure.core/ex-message e)))))))) + (err! (str (:name t) " crashed: " (err-text e)))))))) (defn run-registered [] (doseq [t @registry] (run-one t))