Search code examples
error-handlingclojurestack-traceclojurescriptre-frame

How to find my own functions in a ClojureScript error message?


I am a new ClojureScript user and I'm writing an application using Re-frame. When I get an error message (from ClojureScript), in most cases, I get a call stack ending in JavaScript code from a library. That is expected, but I don't get a function from my own code in the stack! Sometimes, I don't get any ClojureScript function calls at all, just JavaScript's. Is there a way to see the top of the stack in these error messages? Or to see the last function from my code/namespace in the stack?

That could be a huge help to me. Even small mistakes (such as, swapping operator's positions in a map call) are very hard to track. I should be doing something wrong.


Solution

  • It is said that ClojureScript error messages are an acquired taste. Because of the way the compiler works error messages can be cryptic.

    What can help make ClojureScript error messages more readable is installing cljs-devtools or the fork Dirac. This has among other things:

    1. The :hints feature.

      The :hints feature is an attempt to augment uncaught exceptions and error object to include a bit of additional knowledge related to such errors. It tries to fetch the original source file, extract relevant part to show you more context and mark the javascript error there. This is expected to work only with :optimizations none compiler mode and it is disabled by default because it relies on monkey patching.

    2. Better display of ClojureScript function names.

      Example of nicer stack trace (from Dirac, but cljs-webtools already improves it a lot)

      stack trace

    Installation

    • Enable custom formatters
    • Open DevTools with CMD-ALT-J
    • Go to Settings with F1 or by pressing the three dots
    • Check "Enable custom formatters" under Console

    cljs-webtools

    (See Installation):

    • Add configuration to the compiler in project.clj

      {:builds
         [{:id           "dev"
           :source-paths ["src/cljs"]
           :figwheel     {:on-jsload "blabla.core/reload"}
           :compiler     {(...)
                          :preloads        [devtools.preload]
                          :external-config {:devtools/config {:features-to-install :all}}}}
      

    Dirac

    • Install the Dirac Chrome extension.
    • Run Chrome with remote debugging enabled.

      /Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary \
        --remote-debugging-port=9222 \
        --no-first-run \
        --user-data-dir=$A_PATH_TO_YOUR_USER_PROFILE_DIRECTORY
      
    • Add binaryage/dirac to dependencies in your project.clj

      :dependencies [[binaryage/dirac "RELEASE"]]
      

      (or use another one of the installation instructions).

    If you use the re-frame Leiningen template the cljs-devtools are included by default