If an exception is thrown that contains unprintable ex-data, calling print-stack-trace will fail because print-throwable will throw an exception, making it very hard to debug certain failures.
(defn print-throwable
"Prints the class and message of a Throwable. Prints the ex-data map
if present."
{:added "1.1"}
[^Throwable tr]
(printf "%s: %s" (.getName (class tr)) (.getMessage tr))
(when-let [info (ex-data tr)]
(newline)
(pr info)))
Unprintable ex-data could include a third-party record type that implements multiple interfaces that conflict for print-method but did not anticipate making the record printable.
Wrapping that (pr info) in (try .. (catch Throwable t and printing something like (str "<unprintable ex-data: " (ex-message t)">)" might be a reasonable compromise here to allow for easier debugging.