This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-05-27
Channels
- # aws (7)
- # babashka (145)
- # beginners (83)
- # calva (18)
- # cider (11)
- # clara (9)
- # clj-kondo (59)
- # cljdoc (4)
- # cljs-dev (4)
- # cljsrn (11)
- # clojure (168)
- # clojure-australia (21)
- # clojure-dev (5)
- # clojure-europe (46)
- # clojure-italy (3)
- # clojure-nl (10)
- # clojure-taiwan (1)
- # clojure-uk (55)
- # clojurescript (85)
- # clojureverse-ops (1)
- # code-reviews (3)
- # conjure (22)
- # cursive (3)
- # datahike (3)
- # datomic (4)
- # emacs (5)
- # helix (20)
- # jackdaw (1)
- # jobs (2)
- # jobs-discuss (7)
- # lsp (1)
- # malli (5)
- # off-topic (85)
- # other-languages (4)
- # practicalli (4)
- # reitit (2)
- # releases (2)
- # sci (62)
- # shadow-cljs (181)
- # testing (5)
- # tools-deps (15)
- # xtdb (31)
At work we just ran into a situation where Clojure was trying to report-error
, which calls pprint
on the exception, and the ex-data
in the exception is not printable so printing code blew up so you lose the exception information completely. Would there be interest in making report-error
more robust so you still get useful output from it, or would this be considered too much of an edge case?
non printable ex-data is weird to me, as I rarely use ex-data for anything other than printing (so I know more about the exception context in the printed output)
Specifically, this is a case where ex-data
is essentially a lazy sequence and realizing it throws an exception (it’s a bit more complex than that but…).
Hmm, in trying to boil this down to a simpler repro case, I can’t actually get a version that loses exception data like we’re seeing at work.
Example of what I’m talking about:
(! 536)-> cat blowup.clj
(def bad (delay (/ 1 0)))
(def wrap (lazy-seq (cons @bad [])))
(throw (ex-info "boom" {:explode wrap}))
(! 537)-> clojure -M blowup.clj
Exception in thread "main" java.lang.ArithmeticException: Divide by zero
at clojure.lang.Numbers.divide(Numbers.java:188)
at clojure.lang.Numbers.divide(Numbers.java:3901)
at user$fn__136.invokeStatic(blowup.clj:1)
at user$fn__136.invoke(blowup.clj:1)
at clojure.lang.Delay.deref(Delay.java:42)
at clojure.core$deref.invokeStatic(core.clj:2324)
at clojure.core$deref.invoke(core.clj:2310)
at user$fn__138.invokeStatic(blowup.clj:3)
at user$fn__138.invoke(blowup.clj:3)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
...
at clojure.pprint$pprint.invoke(pprint_base.clj:241)
at clojure.lang.Var.invoke(Var.java:384)
at clojure.main$report_error$fn__9184$fn__9185.invoke(main.clj:603)
at clojure.main$report_error$fn__9184.invoke(main.clj:602)
at clojure.main$report_error.invokeStatic(main.clj:601)
at clojure.main$main.invokeStatic(main.clj:666)
at clojure.main$main.doInvoke(main.clj:616)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:40)
Instead of getting a single line error and an EDN file. You get the underlying exception but you don’t get any info about the ex-info
that was actually thrown.