From 5c977a348b54a12bd42f568201ad2db226408df1 Mon Sep 17 00:00:00 2001 From: Peter Taoussanis Date: Mon, 23 Dec 2024 09:55:13 +0100 Subject: [PATCH] [doc] Better document pattern of using `trace!`/`spy!` with `catch->error!` --- .../main/resources/signal-docstrings/spy!.txt | 14 ++++++++++++-- .../main/resources/signal-docstrings/trace!.txt | 14 ++++++++++++-- projects/main/test/taoensso/telemere_tests.cljc | 16 ++++++++++++++-- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/projects/main/resources/signal-docstrings/spy!.txt b/projects/main/resources/signal-docstrings/spy!.txt index 6359859..3fdb9b8 100644 --- a/projects/main/resources/signal-docstrings/spy!.txt +++ b/projects/main/resources/signal-docstrings/spy!.txt @@ -53,8 +53,18 @@ Tips: - Execution of `run` form may create additional (nested) signals. Each signal's `:parent` key will indicate its immediate parent. - - Can be useful to wrap with `catch->error!`: - (catch->error! ::error-id (spy! ...)). + - It's often useful to wrap `run` form with `catch->error!`: + (trace! ::trace-id (catch->error! ::error-id ...)). + + This way you have independent filtering for `run` forms that throw, + allowing you to use a higher min level and/or reduced sampling, etc. + + In this case you'll create: + 0 or 1 `:trace` signals (depending on filtering), AND + 0 or 1 `:error` signals (depending on filtering). + + Note that the `:error` signal will contain tracing info (e.g. `:parent` key) + iff the enclosing `trace!` is allowed. - Runtime of async or lazy code in `run` form will intentionally NOT be included in resulting signal's `:run-nsecs` value. If you want to measure diff --git a/projects/main/resources/signal-docstrings/trace!.txt b/projects/main/resources/signal-docstrings/trace!.txt index d6c10c9..74c202e 100644 --- a/projects/main/resources/signal-docstrings/trace!.txt +++ b/projects/main/resources/signal-docstrings/trace!.txt @@ -53,8 +53,18 @@ Tips: - Execution of `run` form may create additional (nested) signals. Each signal's `:parent` key will indicate its immediate parent. - - Can be useful to wrap with `catch->error!`: - (catch->error! ::error-id (trace! ...)). + - It's often useful to wrap `run` form with `catch->error!`: + (trace! ::trace-id (catch->error! ::error-id ...)). + + This way you have independent filtering for `run` forms that throw, + allowing you to use a higher min level and/or reduced sampling, etc. + + In this case you'll create: + 0 or 1 `:trace` signals (depending on filtering), AND + 0 or 1 `:error` signals (depending on filtering). + + Note that the `:error` signal will contain tracing info (e.g. `:parent` key) + iff the enclosing `trace!` is allowed. - Default level is `:info`, not `:trace`! The name "trace" in "trace signal" refers to the general action of tracing program flow rather than to the diff --git a/projects/main/test/taoensso/telemere_tests.cljc b/projects/main/test/taoensso/telemere_tests.cljc index 90f1b2a..0917727 100644 --- a/projects/main/test/taoensso/telemere_tests.cljc +++ b/projects/main/test/taoensso/telemere_tests.cljc @@ -591,7 +591,13 @@ (let [[[_ re] [sv]] (with-sigs (tel/trace! :id1 (ex1!))) ] [(is (ex1? re)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id :id1, :error pex1?, :msg_ #?(:clj "(ex1!) !> clojure.lang.ExceptionInfo" :cljs "(ex1!) !> cljs.core/ExceptionInfo")}))]) - (let [[[rv] [sv]] (with-sigs (tel/trace! {:allow? false} (+ 1 2))) ] [(is (= rv 3)) (is (nil? sv))]) + (let [[[rv] [sv]] (with-sigs (tel/trace! {:allow? false} (+ 1 2)))] [(is (= rv 3)) (is (nil? sv))]) + + (testing "Use with `catch->error!`" + (let [[[_ re] [sv1 sv2]] (with-sigs (tel/trace! ::id1 (tel/catch->error! ::id2 (ex1!))))] + [(is (ex1? re)) + (is (sm? sv1 {:kind :error, :line :submap/some, :level :error, :id ::id2, :error ex1, :parent {:id ::id1}})) + (is (sm? sv2 {:kind :trace, :line :submap/some, :level :info, :id ::id1, :error ex1, :root {:id ::id1}}))])) (testing ":run-form" ; Undocumented, experimental [(is (sm? (with-sig (tel/trace! :non-list)) {:run-form :non-list})) @@ -612,7 +618,13 @@ (let [[[_ re] [sv]] (with-sigs (tel/spy! :warn (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :spy, :line :submap/some, :level :warn, :error pex1?, :msg_ #?(:clj "(ex1!) !> clojure.lang.ExceptionInfo" :cljs "(ex1!) !> cljs.core/ExceptionInfo")}))]) - (let [[[rv] [sv]] (with-sigs (tel/spy! {:allow? false} (+ 1 2))) ] [(is (= rv 3)) (is (nil? sv))])]) + (let [[[rv] [sv]] (with-sigs (tel/spy! {:allow? false} (+ 1 2))) ] [(is (= rv 3)) (is (nil? sv))]) + + (testing "Use with `catch->error!`" + (let [[[_ re] [sv1 sv2]] (with-sigs (tel/spy! :warn (tel/catch->error! :error (ex1!))))] + [(is (ex1? re)) + (is (sm? sv1 {:kind :error, :line :submap/some, :level :error, :error ex1, :parent {}})) + (is (sm? sv2 {:kind :spy, :line :submap/some, :level :warn, :error ex1, :root {}}))]))]) (testing "error!" ; ?id + error => unconditional given error [(let [[[rv] [sv]] (with-sigs (tel/error! ex1)) ] [(is (ex1? rv)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id nil}))])