diff --git a/src/duct/handler/static.clj b/src/duct/handler/static.clj index 6a00a3b..a841048 100644 --- a/src/duct/handler/static.clj +++ b/src/duct/handler/static.clj @@ -49,6 +49,11 @@ (defmethod ig/init-key ::bad-request [_ response] (make-handler (assoc response :status 400))) +(defmethod ig/init-key ::bad-request-malformed [_ response] + (let [handler (make-handler (assoc response :status 400))] + (fn [_ _ request] + (handler request)))) + (defmethod ig/init-key ::not-found [_ response] (make-handler (assoc response :status 404))) diff --git a/src/duct/middleware/web.clj b/src/duct/middleware/web.clj index 72117ac..8fd2560 100644 --- a/src/duct/middleware/web.clj +++ b/src/duct/middleware/web.clj @@ -1,5 +1,6 @@ (ns duct.middleware.web - (:require [duct.logger :as logger] + (:require [cheshire.core :as cheshire] + [duct.logger :as logger] [integrant.core :as ig] [muuntaja.core :as mc] [muuntaja.middleware :as mm] @@ -129,5 +130,14 @@ (merge-with deep-merge a b) b)) -(defmethod ig/init-key ::format [_ options] - #(mm/wrap-format % (deep-merge mc/default-options options))) +(defmethod ig/init-key ::format [_ {:keys [malformed-handler] + :as options + :or {malformed-handler + (fn [error content-type request] + (let [handler (:malformed-handler options)] + (-> (handler error content-type request) + (update :body cheshire/generate-string) + (assoc-in [:headers "Content-Type"] "application/json"))))}}] + #(mm/wrap-exception + (mm/wrap-format % (deep-merge mc/default-options options)) + malformed-handler)) diff --git a/src/duct/module/web.clj b/src/duct/module/web.clj index d704fc5..1c7ae03 100644 --- a/src/duct/module/web.clj +++ b/src/duct/module/web.clj @@ -70,6 +70,7 @@ (def ^:private base-config {:duct.handler.static/bad-request (plaintext-response "Bad Request") + :duct.handler.static/bad-request-malformed (plaintext-response "Bad Request Malformed") :duct.handler.static/not-found (plaintext-response "Not Found") :duct.handler.static/method-not-allowed (plaintext-response "Method Not Allowed") :duct.handler.static/internal-server-error (plaintext-response "Internal Server Error") @@ -80,11 +81,12 @@ (def ^:private api-config {:duct.handler.static/bad-request {:body ^:displace {:error :bad-request}} + :duct.handler.static/bad-request-malformed {:body ^:displace {:error :malformed-request-body}} :duct.handler.static/not-found {:body ^:displace {:error :not-found}} :duct.handler.static/method-not-allowed {:body ^:displace {:error :method-not-allowed}} :duct.handler.static/internal-server-error {:body ^:displace {:error :internal-server-error}} - :duct.middleware.web/format {} + :duct.middleware.web/format {:malformed-handler (ig/ref :duct.handler.static/bad-request-malformed)} :duct.middleware.web/defaults base-ring-defaults :duct.core/handler {:middleware ^:distinct [(ig/ref :duct.middleware.web/not-found) @@ -113,6 +115,7 @@ (defn- site-config [project-ns] {:duct.handler.static/bad-request (html-response error-400) + :duct.handler.static/bad-request-malformed (html-response error-400) :duct.handler.static/not-found (html-response error-404) :duct.handler.static/method-not-allowed (html-response error-405) :duct.handler.static/internal-server-error (html-response error-500) diff --git a/test/duct/module/web_test.clj b/test/duct/module/web_test.clj index 7181d14..42d8af4 100644 --- a/test/duct/module/web_test.clj +++ b/test/duct/module/web_test.clj @@ -58,6 +58,9 @@ :duct.handler.static/bad-request {:headers {"Content-Type" "text/plain; charset=UTF-8"} :body "Bad Request"} + :duct.handler.static/bad-request-malformed + {:headers {"Content-Type" "text/plain; charset=UTF-8"} + :body "Bad Request Malformed"} :duct.handler.static/not-found {:headers {"Content-Type" "text/plain; charset=UTF-8"} :body "Not Found"} @@ -102,13 +105,16 @@ :logger (ig/ref :duct/logger)} :duct.handler.static/bad-request {:body {:error :bad-request}} + :duct.handler.static/bad-request-malformed + {:body {:error :malformed-request-body}} :duct.handler.static/not-found {:body {:error :not-found}} :duct.handler.static/method-not-allowed {:body {:error :method-not-allowed}} :duct.handler.static/internal-server-error {:body {:error :internal-server-error}} - :duct.middleware.web/format {} + :duct.middleware.web/format + {:malformed-handler (ig/ref :duct.handler.static/bad-request-malformed)} :duct.middleware.web/stacktrace {} :duct.middleware.web/hide-errors {:error-handler (ig/ref :duct.handler.static/internal-server-error)} @@ -155,6 +161,9 @@ :duct.middleware.web/webjars {} :duct.middleware.web/stacktrace {} :duct.handler.static/bad-request + {:headers {"Content-Type" "text/html; charset=UTF-8"} + :body (io/resource "duct/module/web/errors/400.html")} + :duct.handler.static/bad-request-malformed {:headers {"Content-Type" "text/html; charset=UTF-8"} :body (io/resource "duct/module/web/errors/400.html")} :duct.handler.static/not-found