diff --git a/CHANGELOG.md b/CHANGELOG.md index 63eb042..e77c5d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,49 @@ +# 🔥 [Unreleased](https://github.com/tami5/clj-duct-reitit) + + +### Exceptions + + +
d5c2be8 ✨ Feature: Auto-detect user exceptions handler
When user defined `project-ns.handler/exceptions` or +`project.ns.handler.exceptions/main` it should auto-detected and set it +
+ +### Logging + + +
a7f3d6b ✨ Feature: Support request logging
Example Output: + +Pretty Mode: + +~~~clojure +Starting Request ------------------------ + +Request Time: 10:53:27 +Request Method: "GET" +Request URI: "/divide" +Request Params: {:body {:y 2, :x 2}} + +----------------------------------------- + +Finishing Request ------------------------ + +Request Method: "GET" +Request URI: "/divide" +Request Duration: 0 ms + +------------------------------------------ +~~~ + +Compact Mode: + +~~~clojure +[:starting {:method GET, :uri /divide, :params {:body {:y 2, :x 2}}}] +[:completed {:method GET, :uri /divide, :completed-in 0}] +~~~ +
+ + + # 🎉 [0.3.0](https://github.com/tami5/clj-duct-reitit/tree/0.3.0) - 2022-01-09 diff --git a/README.md b/README.md index c0b30af..a6372e0 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,8 @@ Full configuration demo: ;; Global middleware to be injected. expected registry key only :duct.reitit/middleware [] - ;; Exception handling configuration + ;; Exception handling configuration. Auto-detected for + :foo.handler/exceptions and :foo.handler.exceptions/main :duct.reitit/exception #ig/ref :foo.handler/exceptions ;; Coercion configuration @@ -138,6 +139,10 @@ around [ring-reitit-exception-middleware]. It expects a map of exception classes or `reitit.ring.middleware.exception` keys like wrap or default, and a function that takes `[exception request]`. +It will be auto-detected if the user have the exceptions handler +defined in either `:project-ns.handler/exceptions` or +`:project-ns.handler.exceptions/main` integrant keys. + [ring-reitit-exception-middleware]: https://cljdoc.org/d/metosin/reitit/0.5.15/doc/ring/exception-handling-with-ring#exceptioncreate-exception-middleware #### `duct.reitit/cross-origin` diff --git a/src/duct/reitit.clj b/src/duct/reitit.clj index 58f0218..92db05f 100644 --- a/src/duct/reitit.clj +++ b/src/duct/reitit.clj @@ -5,7 +5,7 @@ [duct.reitit.defaults :refer [reitit-module-defaults]] [duct.reitit.handler] [duct.reitit.log] - [duct.reitit.util :as util :refer [get-namespaces resolve-key]] + [duct.reitit.util :as util :refer [get-namespaces resolve-key spy]] [integrant.core :refer [init-key] :as ig])) (defn registry-resolve @@ -37,15 +37,23 @@ (let [profile-config (some-> user-config :duct.core/environment reitit-module-defaults)] (merge-configs (reitit-module-defaults :base) profile-config user-config))) +(defn ^:private auto-detect-exception [namespaces config] + (let [as-handler (keyword (first namespaces) "exceptions") + as-main (keyword (str (first namespaces) ".exceptions") "main") + handler-ref (when (config as-handler) (ig/ref as-handler)) + main-ref (when (config as-main) (ig/ref as-main))] + {::options {:exception (or handler-ref main-ref)}})) + (defmethod init-key :duct.module/reitit [_ _] - (fn [{:duct.reitit/keys [registry routes] :as user-config}] + (fn [{:duct.reitit/keys [registry routes exception] :as user-config}] (let [config (get-config user-config) namespaces (get-namespaces config) registry (registry-resolve namespaces registry)] (module/init {:root :duct.reitit :config config - :extra [(registry-tree registry)] + :extra [(registry-tree registry) + (when-not exception (auto-detect-exception namespaces config))] :store {:namespaces namespaces :routes routes} :schema {::registry (registry-references registry) ::routes [:routes :namespaces ::registry] diff --git a/test/duct/reitit_test.clj b/test/duct/reitit_test.clj index e7462b6..ae85c2e 100644 --- a/test/duct/reitit_test.clj +++ b/test/duct/reitit_test.clj @@ -8,7 +8,8 @@ [duct.test-helpers :refer [base-config init-system request with-base-config test-options routes]] [reitit.core :as r] [duct.reitit.util :refer [to-edn spy]] - [clojure.string :as str])) + [clojure.string :as str] + [medley.core :refer [dissoc-in]])) (core/load-hierarchy) @@ -123,6 +124,10 @@ (is (= {:y 0 :x 0} (:data divide-by-zero-response))) (is (= "No parameters received" (:cause no-params-response))))))) +(deftest test-auto-exception-handlers-detection + (let [system (init-system (dissoc-in (with-base-config {}) [:duct.profile/base :duct.reitit/exception]))] + (is (get-in system [:duct.reitit/options :exception])))) + (defn- req-with-cfg [{:keys [req-opts config with-str? testfn]}] (let [request (apply request req-opts) handler (-> config with-base-config init-system :duct.reitit/handler)]