Logging readable ClojureScript (.cljs) errors to sentry!!
Tags: clojure, javascript, sentry, clojurescript
Published: 2022-03-10 14:26:24

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](https://www.npmjs.com/package/@sentry/browser) and add an error boundary component as follows:_

- Example below uses re-frame and reagent

```clojure
(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))})))
```

## **Step 2**: _Source maps!_
### 2.1 _why do we need them?_
[Clojurescript](https://clojurescript.org/index) is a compiler for Clojure that targets JavaScript.

ClojureScript [compiles to JS](https://clojurescript.org/reference/advanced-compilation) 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):
```edn
...
:release
         {:build-options
            {:ns-aliases {day8.re-frame.tracing day8.re-frame.tracing-stubs}},
          :compiler-options {:source-map true}},
...
```
### 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](https://docs.sentry.io/product/releases/)
example bash command
```sh
sentry-cli releases new <release-name>
```

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` :-)
```sh
# 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
```

Finally, push your source maps to sentry
```sh
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>/
```

Finalize release 
```sh
sentry-cli releases finalize <release name>
```

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

![your sentry stack trace :-)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ue3tlgwrimjrax7xv5ie.png)