Skip to content
Juho Teperi edited this page Dec 18, 2015 · 12 revisions

All exceptions should be handled gracefully. Compojure-api ships with customizable exception handling with good defaults. Customization is done via api options - delegating to compojure.api.middleware/wrap-exceptions, which does the real work. It catches all thrown exceptions and selects a custom handler based on the thrown exception ex-data or Slingshot value of key :type. If an exception doesn't have ex-data (e.g. legacy Java Exceptions), :compojure.api.exception/default type is used. Exception handlers are 3-arity functions, getting the exception, ex-data and request as arguments. Below are the default type definitions and default handling:

type what default
:compojure.api.exception/request-parsing Input data de-serialization errors. 400 + error in body
:compojure.api.exception/request-validation Request Schema coercion errors. 400 + schema error in body
:compojure.api.exception/response-validation Response Schema coercion errors. 500 + schema error in body
:compojure.api.exception/default Everything else. 500 + print stacktrace + safe message

example to override the default case + add a custom exception type + handler for it:

(defn custom-handler [^Exception e data request]
  (internal-server-error {:message (.getMessage e)}))

(defn calm-handler [^Exception e data request]
  (enhance-your-calm {:message (.getMessage e), :data data}))

(defapi
  {:exceptions {:handlers {:compojure.api.exception/default custom-handler
                           ::calm calm-handler}}}
  (GET* "/bang" [] (throw (RuntimeException. "kosh")))
  (GET* "/calm" [] (throw (ex-info "fail" {:type ::calm, :oil "snake"}))))

Clone this wiki locally