mirror of
https://github.com/metosin/reitit.git
synced 2025-12-20 09:31:11 +00:00
exception middleware tests
This commit is contained in:
parent
b524736776
commit
805cb94d33
3 changed files with 126 additions and 21 deletions
|
|
@ -13,6 +13,9 @@
|
|||
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))
|
||||
|
|
@ -37,13 +40,13 @@
|
|||
(defn request-parsing-handler [_ {:keys [format]} _]
|
||||
{:status 400
|
||||
:headers {"Content-Type" "text/plain"}
|
||||
:body (str "Malformed " format " request.")})
|
||||
:body (str "Malformed " (pr-str format) " request.")})
|
||||
|
||||
;;
|
||||
;; public api
|
||||
;;
|
||||
|
||||
(def default-handlers
|
||||
(def default-options
|
||||
{::default default-handler
|
||||
::ring/response http-response-handler
|
||||
:muuntaja/decode request-parsing-handler
|
||||
|
|
@ -54,17 +57,20 @@
|
|||
"Catches all exceptions and looks up a exception handler:
|
||||
1) `:type` of ex-data
|
||||
2) Class of Exception
|
||||
3) Super Classes of Exception
|
||||
4) The ::default handler"
|
||||
3) descadents `:type` of ex-data
|
||||
4) Super Classes of Exception
|
||||
5) The ::default handler"
|
||||
([]
|
||||
(create-exceptions-middleware default-handlers))
|
||||
([{:keys [handlers] :or {handlers default-handlers}}]
|
||||
(let [default-handler (get handlers ::default default-handler)
|
||||
(create-exceptions-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 handlers e request))
|
||||
(respond (call-error-handler default-handler options e request))
|
||||
(catch Exception e
|
||||
(raise e))))]
|
||||
{:name ::exception
|
||||
:wrap (fn [handler]
|
||||
(fn
|
||||
([request]
|
||||
(try
|
||||
|
|
@ -75,4 +81,4 @@
|
|||
(try
|
||||
(handler request respond (fn [e] (on-exception e request respond raise)))
|
||||
(catch Throwable e
|
||||
(on-exception e request respond raise))))))))
|
||||
(on-exception e request respond raise))))))})))
|
||||
|
|
|
|||
100
test/clj/reitit/ring/middleware/exception_test.clj
Normal file
100
test/clj/reitit/ring/middleware/exception_test.clj
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
(ns reitit.ring.middleware.exception-test
|
||||
(:require [clojure.test :refer [deftest testing is]]
|
||||
[reitit.ring :as ring]
|
||||
[reitit.ring.middleware.exception :as exception]
|
||||
[reitit.coercion.spec]
|
||||
[reitit.ring.coercion]
|
||||
[muuntaja.core :as m])
|
||||
(:import (java.sql SQLException SQLWarning)))
|
||||
|
||||
(derive ::kikka ::kukka)
|
||||
|
||||
(deftest exception-test
|
||||
(letfn [(create [f]
|
||||
(ring/ring-handler
|
||||
(ring/router
|
||||
[["/defaults"
|
||||
{:handler f}]
|
||||
["/coercion"
|
||||
{:middleware [reitit.ring.coercion/coerce-request-middleware
|
||||
reitit.ring.coercion/coerce-response-middleware]
|
||||
:coercion reitit.coercion.spec/coercion
|
||||
:parameters {:query {:x int?, :y int?}}
|
||||
:responses {200 {:body {:total pos-int?}}}
|
||||
:handler f}]]
|
||||
{:data {:middleware [(exception/create-exceptions-middleware
|
||||
(merge
|
||||
exception/default-options
|
||||
{::kikka (constantly {:status 200, :body "kikka"})
|
||||
SQLException (constantly {:status 200, :body "sql"})}))]}})))]
|
||||
|
||||
(testing "normal calls work ok"
|
||||
(let [response {:status 200, :body "ok"}
|
||||
app (create (fn [_] response))]
|
||||
(is (= response (app {:request-method :get, :uri "/defaults"})))))
|
||||
|
||||
(testing "unknown exception"
|
||||
(let [app (create (fn [_] (throw (NullPointerException.))))]
|
||||
(is (= {:status 500
|
||||
:body {:type "exception"
|
||||
:class "java.lang.NullPointerException"}}
|
||||
(app {:request-method :get, :uri "/defaults"}))))
|
||||
(let [app (create (fn [_] (throw (ex-info "fail" {:type ::invalid}))))]
|
||||
(is (= {:status 500
|
||||
:body {:type "exception"
|
||||
:class "clojure.lang.ExceptionInfo"}}
|
||||
(app {:request-method :get, :uri "/defaults"})))))
|
||||
|
||||
(testing "::ring/response"
|
||||
(let [response {:status 200, :body "ok"}
|
||||
app (create (fn [_] (throw (ex-info "fail" {:type ::ring/response, :response response}))))]
|
||||
(is (= response (app {:request-method :get, :uri "/defaults"})))))
|
||||
|
||||
(testing ":muuntaja/decode"
|
||||
(let [app (create (fn [_] (m/decode m/instance "application/json" "{:so \"invalid\"}")))]
|
||||
(is (= {:body "Malformed \"application/json\" request."
|
||||
:headers {"Content-Type" "text/plain"}
|
||||
:status 400}
|
||||
(app {:request-method :get, :uri "/defaults"}))))
|
||||
|
||||
(testing "::coercion/request-coercion"
|
||||
(let [app (create (fn [{{{:keys [x y]} :query} :parameters}]
|
||||
{:status 200, :body {:total (+ x y)}}))]
|
||||
|
||||
(let [{:keys [status body]} (app {:request-method :get
|
||||
:uri "/coercion"
|
||||
:query-params {"x" "1", "y" "2"}})]
|
||||
(is (= 200 status))
|
||||
(is (= {:total 3} body)))
|
||||
|
||||
(let [{:keys [status body]} (app {:request-method :get
|
||||
:uri "/coercion"
|
||||
:query-params {"x" "abba", "y" "2"}})]
|
||||
(is (= 400 status))
|
||||
(is (= :reitit.coercion/request-coercion (:type body))))
|
||||
|
||||
(let [{:keys [status body]} (app {:request-method :get
|
||||
:uri "/coercion"
|
||||
:query-params {"x" "-10", "y" "2"}})]
|
||||
(is (= 500 status))
|
||||
(is (= :reitit.coercion/response-coercion (:type body)))))))
|
||||
|
||||
(testing "exact :type"
|
||||
(let [app (create (fn [_] (throw (ex-info "fail" {:type ::kikka}))))]
|
||||
(is (= {:status 200, :body "kikka"}
|
||||
(app {:request-method :get, :uri "/defaults"})))))
|
||||
|
||||
(testing "parent :type"
|
||||
(let [app (create (fn [_] (throw (ex-info "fail" {:type ::kukka}))))]
|
||||
(is (= {:status 200, :body "kikka"}
|
||||
(app {:request-method :get, :uri "/defaults"})))))
|
||||
|
||||
(testing "exact Exception"
|
||||
(let [app (create (fn [_] (throw (SQLException.))))]
|
||||
(is (= {:status 200, :body "sql"}
|
||||
(app {:request-method :get, :uri "/defaults"})))))
|
||||
|
||||
(testing "Exception SuperClass"
|
||||
(let [app (create (fn [_] (throw (SQLWarning.))))]
|
||||
(is (= {:status 200, :body "sql"}
|
||||
(app {:request-method :get, :uri "/defaults"})))))))
|
||||
|
|
@ -2,9 +2,8 @@
|
|||
(:require [clojure.test :refer [deftest testing is]]
|
||||
[reitit.ring :as ring]
|
||||
[reitit.ring.middleware.muuntaja :as muuntaja]
|
||||
[muuntaja.core :as m]
|
||||
[reitit.swagger :as swagger]
|
||||
[reitit.core :as r]))
|
||||
[muuntaja.core :as m]))
|
||||
|
||||
(deftest muuntaja-test
|
||||
(let [data {:kikka "kukka"}
|
||||
|
|
|
|||
Loading…
Reference in a new issue