From ffecaabb8db12e9037025d74a94fe8ecc49fd82e Mon Sep 17 00:00:00 2001 From: kalekale Date: Tue, 15 Jan 2019 10:14:04 +0200 Subject: [PATCH] Add something to the docs about printing readable spec coercion errors --- doc/coercion/clojure_spec_coercion.md | 66 +++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/doc/coercion/clojure_spec_coercion.md b/doc/coercion/clojure_spec_coercion.md index 96467530..9a410820 100644 --- a/doc/coercion/clojure_spec_coercion.md +++ b/doc/coercion/clojure_spec_coercion.md @@ -58,3 +58,69 @@ Failing coercion: (match-by-path-and-coerce! "/metosin/users/ikitommi") ; => ExceptionInfo Request coercion failed... ``` + +## Error printing + +Spec problems are exposed as-is into request & response coercion errors, enabling pretty-printers like expound to be used: + +```clj +(require '[reitit.ring :as ring]) +(require '[reitit.ring.middleware.exception :as exception]) +(require '[reitit.ring.coercion :as coercion]) +(require '[expound.alpha :as expound]) + +(defn coercion-error-handler [status] + (let [printer (expound/custom-printer {:theme :figwheel-theme, :print-specs? false}) + handler (exception/create-coercion-handler status)] + (fn [exception request] + (printer (-> exception ex-data :problems)) + (handler exception request)))) + +(def app + (ring/ring-handler + (ring/router + ["/plus" + {:get + {:parameters {:query {:x int?, :y int?}} + :responses {200 {:body {:total pos-int?}}} + :handler (fn [{{{:keys [x y]} :query} :parameters}] + {:status 200, :body {:total (+ x y)}})}}] + {:data {:coercion reitit.coercion.spec/coercion + :middleware [(exception/create-exception-middleware + (merge + exception/default-handlers + {:reitit.coercion/request-coercion (coercion-error-handler 400) + :reitit.coercion/response-coercion (coercion-error-handler 500)})) + coercion/coerce-request-middleware + coercion/coerce-response-middleware]}}))) + +(app + {:uri "/plus" + :request-method :get + :query-params {"x" "1", "y" "fail"}}) +; => ... +; -- Spec failed -------------------- +; +; {:x ..., :y "fail"} +; ^^^^^^ +; +; should satisfy +; +; int? + + + +(app + {:uri "/plus" + :request-method :get + :query-params {"x" "1", "y" "-2"}}) +; => ... +;-- Spec failed -------------------- +; +; {:total -1} +; ^^ +; +; should satisfy +; +; pos-int? +```