From 3d730f9c5a7eb6555a06ee417c090336365772fb Mon Sep 17 00:00:00 2001 From: Peter Taoussanis Date: Fri, 23 Feb 2024 15:43:58 +0100 Subject: [PATCH] [fix] [#381] Handle possible invalid stacktrace fonts Pretty v2 introduced an incompatible change to its font format. Few (if any?) Timbre users actually customize these fonts beyond possibly disabling them, so this shouldn't affect most folks. But to be on the safe side, this commit introduces handling for possible v1 style fonts. There's 2 cases: 1. [Compile-time] Invalid default fonts (set via environment variable / JVM property). In this case Timbre will throw, preventing compilation. 2. [Runtime] Invalid fonts in output opts. In this case Timbre will log an error and ignore the invalid fonts. --- src/taoensso/timbre.cljc | 46 +++++++++++++++++++++++++++++---------- wiki/1-Getting-started.md | 4 ++-- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/taoensso/timbre.cljc b/src/taoensso/timbre.cljc index f0050cb2..6133e761 100644 --- a/src/taoensso/timbre.cljc +++ b/src/taoensso/timbre.cljc @@ -899,13 +899,34 @@ :output-opts {:arg->str-fn (fn [_] "x")}})) #?(:clj - (def ^:private default-stacktrace-fonts - (enc/get-env - {:as :edn - :default clj-commons.format.exceptions/default-fonts} - [:taoensso.timbre.default-stacktrace-fonts<.edn> ; Undocumented - :timbre-defaut-stacktrace-fonts<.edn> ; Legacy - ]))) + (do + ;; Pretty v1 used string fonts, v2 uses unrelated keywords + (def ^:private invalid-stacktrace-fonts-msg "Invalid Timbre stacktrace fonts (see `org.clj-commons/pretty` docs)") + (def ^:private valid-stacktrace-fonts? (fn [st-fonts] (not (enc/rsome-kv (fn [k v] (string? v)) st-fonts)))) + (def ^:private default-stacktrace-fonts + (let [st-fonts + (enc/get-env + {:as :edn :default fmt-ex/default-fonts} + [:taoensso.timbre.default-stacktrace-fonts<.edn> ; Undocumented + :timbre-defaut-stacktrace-fonts<.edn> ; Legacy + ])] + + (if (valid-stacktrace-fonts? st-fonts) ; May be nil or {} + (do st-fonts) + (throw + (ex-info invalid-stacktrace-fonts-msg + {:given-fonts st-fonts + :default-fonts fmt-ex/default-fonts}))))) + + (def ^:private valid-stacktrace-fonts! + (enc/fmemoize + (fn [st-fonts] + (if (valid-stacktrace-fonts? st-fonts) + (do st-fonts) + (do + ;; Log error on first encounter + (error invalid-stacktrace-fonts-msg st-fonts) + default-stacktrace-fonts))))))) (defn default-output-error-fn "Default (fn [data]) -> string, used by `default-output-fn` to @@ -935,10 +956,13 @@ (assoc data :?err c)))))) :clj - (binding [fmt-ex/*fonts* - (get output-opts :stacktrace-fonts - default-stacktrace-fonts)] - (fmt-ex/format-exception err))))) + (let [st-fonts + (if-let [e (find output-opts :stacktrace-fonts)] + (valid-stacktrace-fonts! (val e)) + default-stacktrace-fonts)] + + (binding [fmt-ex/*fonts* st-fonts] + (fmt-ex/format-exception err)))))) (comment (default-output-error-fn diff --git a/wiki/1-Getting-started.md b/wiki/1-Getting-started.md index 4274f546..b12c7d26 100644 --- a/wiki/1-Getting-started.md +++ b/wiki/1-Getting-started.md @@ -109,9 +109,9 @@ lein cljsbuild once # Compile js with appropriate logging calls excluded lein uberjar # Compile jar '' ``` -## Stacktrace colors +## Stacktrace fonts -ANSI colors are enabled by default for Clojure stacktraces. To turn these off (e.g. for log files or emails), you can add the following entry to your top-level config or individual appender map/s: +ANSI fonts are enabled by default for Clojure stacktraces being printed to a console. To disable these, add the following entry to your top-level config or individual appender map/s: ```clojure :output-opts {:stacktrace-fonts {}}