From d2f44b801558d497cb4e001b744bb29abaa1fac0 Mon Sep 17 00:00:00 2001 From: Joel Kaasinen Date: Fri, 24 Oct 2025 09:58:03 +0300 Subject: [PATCH] fix: match-by-name! should throw when match-by-name is PartialMatch If a path param was nil, match-by-name (via impl/path-for) was treating the parameter as missing, but match-by-name! (via impl/throw-on-missing-path-params) was treating it as present. That is: (reitit/match-by-name router :page {:id "1"}) ;; => Match (reitit/match-by-name router :page) ;; => PartialMatch (reitit/match-by-name router :page {:id nil}) ;; => PartialMatch (reitit/match-by-name! router :page {:id "1"}) ;; => Match (reitit/match-by-name! router :page) ;; => ExceptionInfo: missing path-params for route /pages/:id -> #{:id} (reitit/match-by-name! router :page {:id nil}) ;; => nil !!! fixes #758 --- modules/reitit-core/src/reitit/impl.cljc | 5 ++--- test/cljc/reitit/core_test.cljc | 12 +++++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/modules/reitit-core/src/reitit/impl.cljc b/modules/reitit-core/src/reitit/impl.cljc index 164cbb82..b65e7b0e 100644 --- a/modules/reitit-core/src/reitit/impl.cljc +++ b/modules/reitit-core/src/reitit/impl.cljc @@ -198,9 +198,8 @@ (:path route))) (defn throw-on-missing-path-params [template required path-params] - (when-not (every? #(contains? path-params %) required) - (let [defined (-> path-params keys set) - missing (set/difference required defined)] + (let [missing (set (remove #(get path-params %) required))] + (when-not (empty? missing) (ex/fail! (str "missing path-params for route " template " -> " missing) {:path-params path-params, :required required})))) diff --git a/test/cljc/reitit/core_test.cljc b/test/cljc/reitit/core_test.cljc index d60f2f41..17c3e4b2 100644 --- a/test/cljc/reitit/core_test.cljc +++ b/test/cljc/reitit/core_test.cljc @@ -13,8 +13,7 @@ (testing "routers handling wildcard paths" (are [r name] - (testing "wild" - + (testing (str name) (testing "simple" (let [router (r/router ["/api" ["/ipa" ["/:size" ::beer]]] {:router r})] (is (= name (r/router-name router))) @@ -52,10 +51,17 @@ :path-params nil}) (r/match-by-name router ::beer))) (is (r/partial-match? (r/match-by-name router ::beer))) + (is (r/partial-match? (r/match-by-name router ::beer {:size nil})) + "nil counts as missing") (is (thrown-with-msg? ExceptionInfo #"^missing path-params for route /api/ipa/:size -> \#\{:size\}$" - (r/match-by-name! router ::beer)))))) + (r/match-by-name! router ::beer))) + (is (thrown-with-msg? + ExceptionInfo + #"^missing path-params for route /api/ipa/:size -> \#\{:size\}$" + (r/match-by-name! router ::beer {:size nil})) + "nil counts as missing")))) (testing "decode %-encoded path params" (let [router (r/router [["/one-param-path/:param1" ::one]