/
stacktrace.clj
57 lines (53 loc) · 1.86 KB
/
stacktrace.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
(ns kaocha.stacktrace
(:require [clojure.stacktrace :as st]
[clojure.string :as str]))
(def ^:dynamic *stacktrace-filters* ["java.lang."
"clojure.test$"
"clojure.lang."
"clojure.core"
"clojure.main"
"orchestra."
"kaocha.monkey_patch"])
(defn elide-element? [e]
(some #(str/starts-with? (.getClassName ^StackTraceElement e) %) *stacktrace-filters*))
(defn print-stack-trace
"Prints a Clojure-oriented stack trace of tr, a Throwable.
Prints a maximum of n stack frames (default: unlimited). Does not print
chained exceptions (causes)."
([tr]
(print-stack-trace tr nil))
([^Throwable tr n]
(let [st (.getStackTrace tr)]
(st/print-throwable tr)
(newline)
(print " at ")
(if-let [e (first st)]
(st/print-trace-element e) ;; always print the first element
(print "[empty stack trace]"))
(newline)
(loop [[e & st] (next st)
eliding? false
n n]
(when e
(let [n (cond-> n n dec)]
(if (= 0 n)
(println " ... and " (count st) "more")
(if (elide-element? e)
(do
(when (not eliding?)
(println " ..."))
(recur st true n))
(do
(print " ")
(st/print-trace-element e)
(newline)
(recur st false n))))))))))
(defn print-cause-trace
"Like print-stack-trace but prints chained exceptions (causes)."
([tr]
(print-cause-trace tr nil))
([tr n]
(print-stack-trace tr n)
(when-let [cause (.getCause ^Throwable tr)]
(print "Caused by: ")
(recur cause n))))