Zodiac provides a flexible error handling system that lets you customize how exceptions are caught and transformed into HTTP responses.
By default, uncaught exceptions return a 500 response with the body "Unknown error". The exception is logged with its stack trace.
Use the :error-handlers option to define custom handlers. Handlers are keyed by exception class or by the :type value in ex-info data.
(require '[zodiac.core :as z])
(defn my-error-handler [exception request]
{:status 500
:body "Something went wrong"})
(z/start {:routes routes
:error-handlers {Exception my-error-handler}})
The handler function receives two arguments:
exception - The thrown exceptionrequest - The Ring request map(z/start {:routes routes
:error-handlers {IllegalArgumentException
(fn [e req]
{:status 400
:body (str "Bad argument: " (.getMessage e))})
java.io.IOException
(fn [e req]
{:status 503
:body "Service unavailable"})}})
For exceptions created with ex-info, you can key handlers by the :type in the exception data:
(defn handler [request]
(throw (ex-info "Not found" {:type ::not-found
:id (:id (:path-params request))})))
(z/start {:routes routes
:error-handlers {::not-found
(fn [e req]
{:status 404
:body (str "Resource not found: "
(:id (ex-data e)))})}})
Error handlers can return any valid Ring response, including HTML or JSON:
;; HTML error response
(z/start {:routes routes
:error-handlers {::not-found
(fn [e req]
(z/html-response 404
[:div
[:h1 "Not Found"]
[:p "The requested resource does not exist."]]))}})
;; JSON error response
(z/start {:routes routes
:error-handlers {::api-error
(fn [e req]
(z/json-response 500
{:error "Internal error"
:code (:code (ex-data e))}))}})
Reitit coercion errors (from parameter validation) can be handled using the ::coercion/request-coercion key:
(require '[reitit.coercion :as coercion])
(z/start {:routes routes
:error-handlers {::coercion/request-coercion
(fn [e req]
(z/json-response 400
{:error "Validation failed"
:details (ex-data e)}))}})
See Routing for more on parameter coercion.
When multiple handlers could match an exception:
:type match (for ex-info) takes precedenceCan you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |