Skip to content

Commit a029366

Browse files
Fix #8 unhandled exception when parsing malformed body
1 parent 6aa5ccb commit a029366

File tree

4 files changed

+33
-5
lines changed

4 files changed

+33
-5
lines changed

src/duct/handler/static.clj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949
(defmethod ig/init-key ::bad-request [_ response]
5050
(make-handler (assoc response :status 400)))
5151

52+
(defmethod ig/init-key ::bad-request-malformed [_ response]
53+
(let [handler (make-handler (assoc response :status 400))]
54+
(fn [_ _ request]
55+
(handler request))))
56+
5257
(defmethod ig/init-key ::not-found [_ response]
5358
(make-handler (assoc response :status 404)))
5459

src/duct/middleware/web.clj

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(ns duct.middleware.web
2-
(:require [duct.logger :as logger]
2+
(:require [cheshire.core :as cheshire]
3+
[duct.logger :as logger]
34
[integrant.core :as ig]
45
[muuntaja.core :as mc]
56
[muuntaja.middleware :as mm]
@@ -129,5 +130,15 @@
129130
(merge-with deep-merge a b)
130131
b))
131132

132-
(defmethod ig/init-key ::format [_ options]
133-
#(mm/wrap-format % (deep-merge mc/default-options options)))
133+
(defmethod ig/init-key ::format [_ {:keys [malformed-handler]
134+
:as options
135+
:or {malformed-handler
136+
(fn [error content-type request]
137+
(let [handler (or (:malformed-handler options)
138+
(:default-malformed-handler options))]
139+
(-> (handler error content-type request)
140+
(update :body cheshire/generate-string)
141+
(assoc-in [:headers "Content-Type"] "application/json"))))}}]
142+
#(mm/wrap-exception
143+
(mm/wrap-format % (deep-merge mc/default-options options))
144+
malformed-handler))

src/duct/module/web.clj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070

7171
(def ^:private base-config
7272
{:duct.handler.static/bad-request (plaintext-response "Bad Request")
73+
:duct.handler.static/bad-request-malformed (plaintext-response "Bad Request Malformed")
7374
:duct.handler.static/not-found (plaintext-response "Not Found")
7475
:duct.handler.static/method-not-allowed (plaintext-response "Method Not Allowed")
7576
:duct.handler.static/internal-server-error (plaintext-response "Internal Server Error")
@@ -80,11 +81,12 @@
8081

8182
(def ^:private api-config
8283
{:duct.handler.static/bad-request {:body ^:displace {:error :bad-request}}
84+
:duct.handler.static/bad-request-malformed {:body ^:displace {:error :malformed-request-body}}
8385
:duct.handler.static/not-found {:body ^:displace {:error :not-found}}
8486
:duct.handler.static/method-not-allowed {:body ^:displace {:error :method-not-allowed}}
8587
:duct.handler.static/internal-server-error
8688
{:body ^:displace {:error :internal-server-error}}
87-
:duct.middleware.web/format {}
89+
:duct.middleware.web/format {:default-malformed-handler (ig/ref :duct.handler.static/bad-request-malformed)}
8890
:duct.middleware.web/defaults base-ring-defaults
8991
:duct.core/handler
9092
{:middleware ^:distinct [(ig/ref :duct.middleware.web/not-found)
@@ -113,6 +115,7 @@
113115

114116
(defn- site-config [project-ns]
115117
{:duct.handler.static/bad-request (html-response error-400)
118+
:duct.handler.static/bad-request-malformed (html-response error-400)
116119
:duct.handler.static/not-found (html-response error-404)
117120
:duct.handler.static/method-not-allowed (html-response error-405)
118121
:duct.handler.static/internal-server-error (html-response error-500)

test/duct/module/web_test.clj

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@
5858
:duct.handler.static/bad-request
5959
{:headers {"Content-Type" "text/plain; charset=UTF-8"}
6060
:body "Bad Request"}
61+
:duct.handler.static/bad-request-malformed
62+
{:headers {"Content-Type" "text/plain; charset=UTF-8"}
63+
:body "Bad Request Malformed"}
6164
:duct.handler.static/not-found
6265
{:headers {"Content-Type" "text/plain; charset=UTF-8"}
6366
:body "Not Found"}
@@ -102,13 +105,16 @@
102105
:logger (ig/ref :duct/logger)}
103106
:duct.handler.static/bad-request
104107
{:body {:error :bad-request}}
108+
:duct.handler.static/bad-request-malformed
109+
{:body {:error :malformed-request-body}}
105110
:duct.handler.static/not-found
106111
{:body {:error :not-found}}
107112
:duct.handler.static/method-not-allowed
108113
{:body {:error :method-not-allowed}}
109114
:duct.handler.static/internal-server-error
110115
{:body {:error :internal-server-error}}
111-
:duct.middleware.web/format {}
116+
:duct.middleware.web/format
117+
{:default-malformed-handler (ig/ref :duct.handler.static/bad-request-malformed)}
112118
:duct.middleware.web/stacktrace {}
113119
:duct.middleware.web/hide-errors
114120
{:error-handler (ig/ref :duct.handler.static/internal-server-error)}
@@ -155,6 +161,9 @@
155161
:duct.middleware.web/webjars {}
156162
:duct.middleware.web/stacktrace {}
157163
:duct.handler.static/bad-request
164+
{:headers {"Content-Type" "text/html; charset=UTF-8"}
165+
:body (io/resource "duct/module/web/errors/400.html")}
166+
:duct.handler.static/bad-request-malformed
158167
{:headers {"Content-Type" "text/html; charset=UTF-8"}
159168
:body (io/resource "duct/module/web/errors/400.html")}
160169
:duct.handler.static/not-found

0 commit comments

Comments
 (0)