Skip to content

Commit

Permalink
feat(exceptions): auto-detect user exceptions handler
Browse files Browse the repository at this point in the history
When user defined `project-ns.handler/exceptions` or
`project.ns.handler.exceptions/main` it should auto-detected and set it

closes #6
  • Loading branch information
kkharji committed Jan 9, 2022
1 parent a7f3d6b commit 2a8c648
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 5 deletions.
46 changes: 46 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,49 @@
# 🔥 [Unreleased](https://github.com/tami5/clj-duct-reitit)


### Exceptions


<dl><dd><details><summary><a href="https://github.com/tami5/clj-duct-reitit/commit/d5c2be889afce888534b503080bd8c26a706e5a1"><tt>d5c2be8</tt></a> ✨ Feature: Auto-detect user exceptions handler</summary><br />When user defined `project-ns.handler/exceptions` or
`project.ns.handler.exceptions/main` it should auto-detected and set it
</details></dd></dl>

### Logging


<dl><dd><details><summary><a href="https://github.com/tami5/clj-duct-reitit/commit/a7f3d6b0956d5ab25a94f37e9f294a1179c08fce"><tt>a7f3d6b</tt></a> ✨ Feature: Support request logging</summary><br />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}]
~~~
</details></dd></dl>



# 🎉 [0.3.0](https://github.com/tami5/clj-duct-reitit/tree/0.3.0) - 2022-01-09


Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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`
Expand Down
14 changes: 11 additions & 3 deletions src/duct/reitit.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand Down
7 changes: 6 additions & 1 deletion test/duct/reitit_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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)]
Expand Down

0 comments on commit 2a8c648

Please sign in to comment.