Raw exception objects show up like any other object in Portal, like it would be printed at the REPL.
However, Portal has a special viewer for exceptions and the good news is that
it's based on the
clojure.datafy/datafy
of
exceptions in Clojure.
To get things wired up so exceptions are auto data-fied before being sent to Portal, try the following:
(ns user
(:require [portal.api :as p]
[clojure.datafy :as d]))
(defn error->data [ex]
(assoc (d/datafy ex) :runtime :clj))
(defn submit [value]
(p/submit
(if-not (instance? Exception value)
value
(error->data value))))
(add-tap #'submit)
(tap> (ex-info "My Error!!!" {:my :data}))
Unfortunately, js/Error
isn't data-fied in ClojureScript, however, you can
provide your own mapping between errors and data.
Here is one such mapping and submit function:
(defn error->data [ex]
(merge
(when-let [data (.-data ex)]
{:data data})
{:runtime :cljs
:cause (.-message ex)
:via [{:type (symbol (.-name (type ex)))
:message (.-message ex)}]
:stack (.-stack ex)}))
(defn submit [value]
(p/submit
(if-not (instance? js/Error value)
value
(error->data value))))
(add-tap #'submit)
(tap> (ex-info "My Error!!!" {:my :data}))
And with that you get the following:
If you would like to funnel all uncaught errors from a web based ClojureScript app, consider adding the following handlers:
(defn- error-handler [event]
(tap> (or (.-error event) (.-reason event))))
(.addEventListener js/window "error" error-handler)
(.addEventListener js/window "unhandledrejection" error-handler)
Similarly for node, the following should work:
(.on js/process "unhandledRejection" tap>)
(.on js/process "uncaughtException" tap>)
Similarly for the JVM, the following should work:
(Thread/setDefaultUncaughtExceptionHandler
(reify Thread$UncaughtExceptionHandler
(uncaughtException [_this t e]
(tap> e))))
However, there is an issues with futures which is explained in this article.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close