Custom Exceptions in Clojure?

Rather than generating custom classes, there are two much simpler ways to use custom exceptions:

  1. Use slingshot – this provides custom throw+ and catch+ macros that let you throw and catch any object, as well as exceptions.

  2. In clojure 1.4 and above, you can use clojure.core/ex-info and clojure.core/ex-data to generate and catch a clojure.lang.ExceptionInfo class, which wraps a message and a map of data.

Using this is straightforward:

(throw (ex-info "My hovercraft is full of eels"
                {:type :python-exception, :cause :eels}))

(try (...)
  (catch clojure.lang.ExceptionInfo e
    (if (= :eels (-> e ex-data :cause))
      (println "beware the shrieking eels!")
      (println "???"))))

Or in a midje test:

(fact "should throw some eels"
    (...) 
    => (throws clojure.lang.ExceptionInfo
          #(= :eels (-> % ex-data :cause))))

Leave a Comment