tune exceptions-middleware

This commit is contained in:
Tommi Reiman 2018-07-22 16:26:28 +03:00
parent 1eef610577
commit 0f384c2b52
2 changed files with 49 additions and 42 deletions

View file

@ -2,26 +2,6 @@
(:require [reitit.coercion :as coercion]
[reitit.ring :as ring]))
(defn- super-classes [^Class k]
(loop [sk (.getSuperclass k), ks []]
(if-not (= sk Object)
(recur (.getSuperclass sk) (conj ks sk))
ks)))
(defn- call-error-handler [default-handler handlers error request]
(let [{:keys [type] :as data} (ex-data error)
ex-class (class error)
error-handler (or (get handlers type)
(get handlers ex-class)
(some
(partial get handlers)
(descendants type))
(some
(partial get handlers)
(super-classes ex-class))
default-handler)]
(error-handler error data request)))
(defn default-handler [^Exception e _ _]
{:status 500
:body {:type "exception"
@ -42,6 +22,46 @@
:headers {"Content-Type" "text/plain"}
:body (str "Malformed " (pr-str format) " request.")})
(defn- super-classes [^Class k]
(loop [sk (.getSuperclass k), ks []]
(if-not (= sk Object)
(recur (.getSuperclass sk) (conj ks sk))
ks)))
(defn- call-error-handler [handlers error request]
(let [{:keys [type] :as data} (ex-data error)
ex-class (class error)
error-handler (or (get handlers type)
(get handlers ex-class)
(some
(partial get handlers)
(descendants type))
(some
(partial get handlers)
(super-classes ex-class))
(get handlers ::default default-handler))]
(error-handler error data request)))
(defn- on-exception [e handlers request respond raise]
(try
(respond (call-error-handler handlers e request))
(catch Exception e
(raise e))))
(defn- wrap [options]
(fn [handler]
(fn
([request]
(try
(handler request)
(catch Throwable e
(on-exception options e request identity #(throw %)))))
([request respond raise]
(try
(handler request respond (fn [e] (on-exception options e request respond raise)))
(catch Throwable e
(on-exception options e request respond raise)))))))
;;
;; public api
;;
@ -53,32 +73,19 @@
::coercion/request-coercion (coercion-handler 400)
::coercion/response-coercion (coercion-handler 500)})
(defn create-exceptions-middleware
(def exception-middleware
"Catches all exceptions and looks up a exception handler:
1) `:type` of ex-data
2) Class of Exception
3) descadents `:type` of ex-data
4) Super Classes of Exception
5) The ::default handler"
{:name ::exception
:wrap (wrap default-options)})
(defn create-exception-middleware
([]
(create-exceptions-middleware default-options))
(create-exception-middleware default-options))
([options]
(let [default-handler (get options ::default default-handler)
on-exception (fn [e request respond raise]
(try
(respond (call-error-handler default-handler options e request))
(catch Exception e
(raise e))))]
{:name ::exception
:wrap (fn [handler]
(fn
([request]
(try
(handler request)
(catch Throwable e
(on-exception e request identity #(throw %)))))
([request respond raise]
(try
(handler request respond (fn [e] (on-exception e request respond raise)))
(catch Throwable e
(on-exception e request respond raise))))))})))
{:name ::exception
:wrap (wrap options)}))

View file

@ -22,7 +22,7 @@
:parameters {:query {:x int?, :y int?}}
:responses {200 {:body {:total pos-int?}}}
:handler f}]]
{:data {:middleware [(exception/create-exceptions-middleware
{:data {:middleware [(exception/create-exception-middleware
(merge
exception/default-options
{::kikka (constantly {:status 200, :body "kikka"})