Skip to end of metadata
Go to start of metadata

Clojure and ClojureScript allow the user to handle platform exceptions with the 'try special form. This page aims to provide a specification for a cross-platform error handling strategy.

UPDATE 2013/11/05

ClojureScript regained its capability to catch all with ticket

The implemented syntax was

There is a pending ticket implementing this syntax for Clojure:


1) Error handling is highly platform dependent, '(try (catch)) directly dispatches on platform type names. There is no platform-independent catch-all clause.

'try special form has a cascaded 'instanceof dispatch built in, which is reasonable for java because it maps directly to the native try{}catch(E e){}, but adds complexity in ClojureScript, where the native try{}catch(e){} is untyped.

2) instanceof is not capable of catching all types because of JS semantics

This won't work! "a string" does not satisfy isinstance of js/String. Instead, you need to check typeof == "string". Similarly, js/Object isn't sufficient either, since strings, numbers, etc don't satisfy isinstance js/Object.


Currently there is no catch-all in clojurescript at all. [CLJS-661]


This proposal considers a generic design for '(try (catch)) expressions, that can be augmented with platform-dependent error handling.

The design should be backwards-compatible with Clojure and ClojureScript and it should be implementable in every Clojure dialect for platforms that have platform-provided escape continuations (i.e. exceptions).

Rejected alternatives

Former ClojureScript's (try* ..  (catch e# ..))

Platform-Error handling should have a basic form that's the same on all platforms. Even if Clojure gained try*, one still couln't mix catching specific exceptions with catch-all.

Proposed solution

In addition to the regular type-dispatched catch clauses, try forms will accept a '(catch* e# ..) clause, that catches all throwables in a platform-independent manner.

The platform-independent subset of 'try forms would essentially amount to '(try .. (catch* e# ..)).

Delivering a more sophisticated mechanism than catch-all, even though included in the scope, is not proposed, because it can be easily implemented as library code.

  1. Nov 04, 2013

    CLJS ticket and patch here:

    I went with the (catch :default e ...) syntax, since that matches multimethods, core.async, and a few other places, plus both I and David Nolen liked it best Smile

    Would be great to spur this to happen for JVM/CLJ as catching Throwable too!

    1. Nov 05, 2013