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)]