-
Notifications
You must be signed in to change notification settings - Fork 147
Exception handling
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"}))))By default only :compojure.api.exception/default handler logs the messages. Since 0.24.5, to add logging to other default handlers you can use function compojure.api.exception/with-logging:
(defapi
{:exceptions {:handlers {::ex/request-parsing (ex/with-logging ex/request-parsing-handler)}}}
(POST* "/bang" [] (ok)))with-logging just wraps the given handler function and calls simple logging function before calling the handler. To control what is logged create your own handlers or own logging wrapper.