Recently my team deployed a new version of our ClojureScript UI and it had a minor bug. It was trivial to fix the problem, a ClojureScript build warning pointed us to the cause. As a result we started thinking it would be nice to have build warnings count as errors and fail our ClojureScript build.

We use Leiningen (version 2.5.3) and lein-cljsbuild (version 1.1.1). After some searching we found that lein-cljsbuild supports specifying custom warning handlers as the value to the :warning-handlers key. The lein-cljsbuild README even provides an example, which we took and added a (System/exit 1) to the end of it. This resulted in a build configuration that looked similar to below.

1 2 3 4 5 6 7 8 9 10 11 { :id "prod" :warning-handlers [( fn [ warning-type env extra ] ( when-let [ s ( cljs.analyzer/error-message warning-type extra )] ( binding [ *out* *err* ] ( println "WARNING:" ( cljs.analyzer/message env s ))) ( System/exit 1 )))] :source-paths [ "src/cljc" "src/cljs" ] :compiler { :output-to "resources/public/js/compiled/ui.js" :externs [ "resources/intercom-externs.js" "resources/mixpanel-externs.js" ] :optimizations :advanced }}

This worked! Well, it sort of worked. Our build failed whenever there was a warning but now we were seeing spurious warnings. We saw “Use of undeclared Var” warnings when functions created in a letfn where calling each other. Definitely not a situation that warrants a warning and definitely not a build failure.

We weren’t seeing this warning before so we opened ClojureScript’s source and found the default warning handler. The default handler checks that warning-type has a truthy value in the map *cljs-warnings* . Inspired by the default handler we added the same check to the start of our warning handler.

1 2 3 4 5 6 :warning-handlers [( fn [ warning-type env extra ] ( when ( warning-type cljs.analyzer/*cljs-warnings* ) ( when-let [ s ( cljs.analyzer/error-message warning-type extra )] ( binding [ *out* *err* ] ( println "WARNING:" ( cljs.analyzer/message env s ))) ( System/exit 1 ))))]