Logging readable ClojureScript (.cljs) errors to sentry!!

frankapiyo

Frankline Apiyo

Posted on March 10, 2022

Logging readable ClojureScript (.cljs) errors to sentry!!

I recently had the pleasure of setting up front-end error reporting for a web application at ona.io. Here's how I did it:

Step 1: Install sentry browser SDK and add an error boundary component as follows:

  • Example below uses re-frame and reagent
(ns your.namespace
  (:require ["@sentry/browser" :as Sentry]
            [reagent.core :as r]
            [re-frame.core :as re-frame]
            ["@sentry/tracing" :refer (Integrations)]))

(defn error-boundary
  [comp]
  (let [error (r/atom nil)]
    (r/create-class
      {:component-did-catch
         (fn [_this e _info]
           (let [{:keys [sentry-dsn app-version env]}
                   @(re-frame/subscribe [::your-configuration-sub])]
             (.init Sentry
                    #js
                     {:environment env,
                      :dsn sentry-dsn,
                      :release app-version,
                      :integrations #js [(new (.-BrowserTracing Integrations))],
                      :tracesSampleRate 1.0})
             (.captureException Sentry e))),
       :get-derived-state-from-error (fn [e] (reset! error e) #js {}),
       :reagent-render (fn [comp]
                         (if @error
                           [:div.fallback-error-ui
                            [:p.alert-danger
                             "An error"]]
                             comp))})))
Enter fullscreen mode Exit fullscreen mode

Step 2: Source maps!

2.1 why do we need them?

Clojurescript is a compiler for Clojure that targets JavaScript.

ClojureScript compiles to JS that is then minified and loaded on/by the browser. source maps keep client-side code readable and more importantly debuggable even after you've combined and minified it, without impacting performance

2.2 how do you generate them?

This depends on how you are compiling your ClojureScript. If you are using shadow-cljs, much like me, this process is simple

Use the following shadow-cljs configs(truncated):

...
:release
         {:build-options
            {:ns-aliases {day8.re-frame.tracing day8.re-frame.tracing-stubs}},
          :compiler-options {:source-map true}},
...
Enter fullscreen mode Exit fullscreen mode

2.3 what do you need them for?

If you are using sentry for error reporting, sentry provides functionality that will use your source maps to make error messages clearer for you

To upload your source maps to sentry, follow these steps:

Create a sentry release
example bash command

sentry-cli releases new <release-name>
Enter fullscreen mode Exit fullscreen mode

Ensure sourceMappingURL is set correctly
From my personal experience, I noticed that sometimes, even after uploading source maps to sentry, your error messages might not look right. The issue might result from sourceMappingURL value in your generated .js files.
so, I fixed with sed :-)

# ensure sourceMappingURL is set correctly
sed -i "s/sourceMappingURL=/sourceMappingURL=$1:\/\/$2\/js\/path\/to\/your\//g" -r resources/public/js/path/to/your/*.js
Enter fullscreen mode Exit fullscreen mode

Finally, push your source maps to sentry

sentry-cli --url https://sentry.io releases --org <org-name> --project <project-name>  files <release-name> upload-sourcemaps resources/public/js/<path to your JS files>/ --url-prefix <protocol>://<your server domain>/js/<path to your JS files>/
Enter fullscreen mode Exit fullscreen mode

Finalize release

sentry-cli releases finalize <release name>
Enter fullscreen mode Exit fullscreen mode

Result

Here's how your stack trace might look like on sentry

your sentry stack trace :-)

💖 💪 🙅 🚩
frankapiyo
Frankline Apiyo

Posted on March 10, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related