From 9e4b420fc8825d1c1ede854748d5bbc3eef9885c Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 5 Apr 2022 17:33:25 +0300 Subject: [PATCH 1/4] on-coercion-error --- .../reitit-frontend/src/reitit/frontend.cljs | 30 ++++++++++++------- .../src/reitit/frontend/history.cljs | 4 +-- test/cljs/reitit/frontend/core_test.cljs | 9 ++++++ 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/modules/reitit-frontend/src/reitit/frontend.cljs b/modules/reitit-frontend/src/reitit/frontend.cljs index 60273f79..20d15b31 100644 --- a/modules/reitit-frontend/src/reitit/frontend.cljs +++ b/modules/reitit-frontend/src/reitit/frontend.cljs @@ -23,17 +23,25 @@ (defn match-by-path "Given routing tree and current path, return match with possibly coerced parameters. Return nil if no match found." - [router path] - (let [uri (.parse Uri path)] - (if-let [match (r/match-by-path router (.getPath uri))] - (let [q (query-params uri) - match (assoc match :query-params q) - ;; Return uncoerced values if coercion is not enabled - so - ;; that tha parameters are always accessible from same property. - parameters (or (coercion/coerce! match) - {:path (:path-params match) - :query q})] - (assoc match :parameters parameters))))) + ([router path] (match-by-path router path nil)) + ([router path {:keys [on-coercion-error]}] + (let [uri (.parse Uri path) + coerce! (if on-coercion-error + (fn [match] + (try (coercion/coerce! match) + (catch js/Error e + (on-coercion-error e) + (throw e)))) + coercion/coerce!)] + (if-let [match (r/match-by-path router (.getPath uri))] + (let [q (query-params uri) + match (assoc match :query-params q) + ;; Return uncoerced values if coercion is not enabled - so + ;; that tha parameters are always accessible from same property. + parameters (or (coerce! match) + {:path (:path-params match) + :query q})] + (assoc match :parameters parameters)))))) (defn match-by-name "Given a router, route name and optionally path-parameters, diff --git a/modules/reitit-frontend/src/reitit/frontend/history.cljs b/modules/reitit-frontend/src/reitit/frontend/history.cljs index 600feaec..f95dcf12 100644 --- a/modules/reitit-frontend/src/reitit/frontend/history.cljs +++ b/modules/reitit-frontend/src/reitit/frontend/history.cljs @@ -40,7 +40,7 @@ nil) (-on-navigate [this path] (reset! last-fragment path) - (on-navigate (rf/match-by-path router path) this)) + (on-navigate (rf/match-by-path router path this) this)) (-get-path [this] ;; Remove # ;; "" or "#" should be same as "#/" @@ -125,7 +125,7 @@ (-on-navigate this (-get-path this)) this)) (-on-navigate [this path] - (on-navigate (rf/match-by-path router path) this)) + (on-navigate (rf/match-by-path router path this) this)) (-stop [this] (gevents/unlistenByKey listen-key) (gevents/unlistenByKey click-listen-key) diff --git a/test/cljs/reitit/frontend/core_test.cljs b/test/cljs/reitit/frontend/core_test.cljs index 22ac1db2..6acb5c1c 100644 --- a/test/cljs/reitit/frontend/core_test.cljs +++ b/test/cljs/reitit/frontend/core_test.cljs @@ -80,6 +80,15 @@ (is (= "/5" (r/match->path (rf/match-by-name router ::foo {:id 5})))) + (testing "coercion error" + (testing "throws without options" + (is (thrown? js/Error (m (rf/match-by-path router "/a"))))) + + (testing "thows and calles on-coercion-error" + (let [exception (atom nil)] + (is (thrown? js/Error (m (rf/match-by-path router "/a" {:on-coercion-error (fn [e] (reset! exception e))})))) + (is (= {:id "a"} (-> @exception (ex-data) :value)))))) + (testing "query param is read" (is (= (r/map->Match {:template "/:id" From 1ecfd1ae0272e5c76954931968018a054238d01d Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 5 Apr 2022 17:55:09 +0300 Subject: [PATCH 2/4] CHANGELOG, pass match too --- CHANGELOG.md | 4 ++++ modules/reitit-frontend/src/reitit/frontend.cljs | 2 +- test/cljs/reitit/frontend/core_test.cljs | 8 ++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc1d1aef..e06f39e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ We use [Break Versioning][breakver]. The version numbers follow a `. @match :path-params))) (is (= {:id "a"} (-> @exception (ex-data) :value)))))) (testing "query param is read" From b282e32b738eedbe6c0be82ed0c048f9248124ae Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Tue, 5 Apr 2022 18:43:34 +0300 Subject: [PATCH 3/4] . --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e06f39e5..2b123b82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ We use [Break Versioning][breakver]. The version numbers follow a `. Date: Tue, 5 Apr 2022 21:22:36 +0300 Subject: [PATCH 4/4] doc the option --- modules/reitit-frontend/src/reitit/frontend.cljs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/reitit-frontend/src/reitit/frontend.cljs b/modules/reitit-frontend/src/reitit/frontend.cljs index d50e9614..d1e9c50a 100644 --- a/modules/reitit-frontend/src/reitit/frontend.cljs +++ b/modules/reitit-frontend/src/reitit/frontend.cljs @@ -22,7 +22,9 @@ (defn match-by-path "Given routing tree and current path, return match with possibly - coerced parameters. Return nil if no match found." + coerced parameters. Return nil if no match found. + + :on-coercion-error - a sideeffecting fn of `match exception -> nil`" ([router path] (match-by-path router path nil)) ([router path {:keys [on-coercion-error]}] (let [uri (.parse Uri path)