Merge pull request #549 from metosin/on-coercion-error

on-coercion-error
This commit is contained in:
Tommi Reiman 2022-04-05 21:23:04 +03:00 committed by GitHub
commit b12c433652
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 14 deletions

View file

@ -12,6 +12,10 @@ We use [Break Versioning][breakver]. The version numbers follow a `<major>.<mino
[breakver]: https://github.com/ptaoussanis/encore/blob/master/BREAK-VERSIONING.md [breakver]: https://github.com/ptaoussanis/encore/blob/master/BREAK-VERSIONING.md
## UNRELEASED
* FIX [#334](https://github.com/metosin/reitit/pull/334) - Frontend: there is no way to catch the exception if coercion fails (via [#549](https://github.com/metosin/reitit/pull/549))
## 0.5.17 (2022-03-10) ## 0.5.17 (2022-03-10)
* FIX match-by-path is broken if there are no non-conflicting wildcard routes [#538](https://github.com/metosin/reitit/issues/538) * FIX match-by-path is broken if there are no non-conflicting wildcard routes [#538](https://github.com/metosin/reitit/issues/538)

View file

@ -22,18 +22,28 @@
(defn match-by-path (defn match-by-path
"Given routing tree and current path, return match with possibly "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.
[router path]
(let [uri (.parse Uri path)] :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)
coerce! (if on-coercion-error
(fn [match]
(try (coercion/coerce! match)
(catch js/Error e
(on-coercion-error match e)
(throw e))))
coercion/coerce!)]
(if-let [match (r/match-by-path router (.getPath uri))] (if-let [match (r/match-by-path router (.getPath uri))]
(let [q (query-params uri) (let [q (query-params uri)
match (assoc match :query-params q) match (assoc match :query-params q)
;; Return uncoerced values if coercion is not enabled - so ;; Return uncoerced values if coercion is not enabled - so
;; that tha parameters are always accessible from same property. ;; that tha parameters are always accessible from same property.
parameters (or (coercion/coerce! match) parameters (or (coerce! match)
{:path (:path-params match) {:path (:path-params match)
:query q})] :query q})]
(assoc match :parameters parameters))))) (assoc match :parameters parameters))))))
(defn match-by-name (defn match-by-name
"Given a router, route name and optionally path-parameters, "Given a router, route name and optionally path-parameters,

View file

@ -40,7 +40,7 @@
nil) nil)
(-on-navigate [this path] (-on-navigate [this path]
(reset! last-fragment 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] (-get-path [this]
;; Remove # ;; Remove #
;; "" or "#" should be same as "#/" ;; "" or "#" should be same as "#/"
@ -125,7 +125,7 @@
(-on-navigate this (-get-path this)) (-on-navigate this (-get-path this))
this)) this))
(-on-navigate [this path] (-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] (-stop [this]
(gevents/unlistenByKey listen-key) (gevents/unlistenByKey listen-key)
(gevents/unlistenByKey click-listen-key) (gevents/unlistenByKey click-listen-key)

View file

@ -80,6 +80,19 @@
(is (= "/5" (is (= "/5"
(r/match->path (rf/match-by-name router ::foo {:id 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)
match (atom nil)]
(is (thrown? js/Error (m (rf/match-by-path router "/a" {:on-coercion-error (fn [m e]
(reset! match m)
(reset! exception e))}))))
(is (= {:id "a"} (-> @match :path-params)))
(is (= {:id "a"} (-> @exception (ex-data) :value))))))
(testing "query param is read" (testing "query param is read"
(is (= (r/map->Match (is (= (r/map->Match
{:template "/:id" {:template "/:id"