Skip to content

Using expound printer for instrument exceptions in the browser #152

@mhuebert

Description

@mhuebert

Recent updates in cljs removed the explain-out string from exception messages. This means exceptions thrown by instrument will not contain a nicely formatted string even if all the instructions for setting up expound have been followed (eg. setting up s/*explain-out*).

These changes to cljs were made with the intention that exceptions should contain only data, and leave formatting/printing to the edges of the system, eg. by a REPL. To help with this, we have the cljs.repl/error->str function, which handles printing of exceptions in a general way (not only spec errors).

What does this mean for the browser? Well, to start, we'll find that exceptions have become less informative than they used to be, until we somehow leverage these new tools to make them meaningful again. There may be numerous approaches to this, each with their own tradeoffs.

a couple of approaches to consider:

  1. print all uncaught exceptions using repl/error->str using a global error handler:
(ns app.core 
  (:require [cljs.spec.alpha :as s]
            [expound.alpha :as expound]
            [cljs.repl :as repl]))

(set! s/*explain-out* expound/printer)

(defn error-handler [message url line column e]
  (js/console.error e)
  (print (repl/error->str e))
  true)

(set! (.-onerror js/window) error-handler)
  1. extend the ExceptionInfo type to always rely on the repl error->str function, so that errors you print in your own try/catch blocks are also formatted:
(extend-type ExceptionInfo
  IPrintWithWriter
  (-pr-writer [o writer opts]
    (-write writer (repl/error->str o))))
  1. augment the console itself to use cljs.repl/error->str to format errors - this would be the domain of tools like cljs-devtools

  2. patch/extend tools to (optionally) include formatted messages in exceptions

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions