]> git.ipfire.org Git - thirdparty/starlette.git/commitdiff
Display missing route details. (#1363)
authorAlex Oleshkevich <alex.oleshkevich@gmail.com>
Mon, 14 Feb 2022 15:57:19 +0000 (18:57 +0300)
committerGitHub <noreply@github.com>
Mon, 14 Feb 2022 15:57:19 +0000 (15:57 +0000)
* Display missing route details.

* Fix formatting.

* Display only path params keys in NoMatchFound error.

* Fix linting issues.

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Tom Christie <tom@tomchristie.com>
starlette/routing.py
tests/test_routing.py

index 03db2ff3e2cd54585ef6f0494eba4e98125d64c8..0388304c9071a856810913f651d1ecdac991c5d7 100644 (file)
@@ -31,6 +31,10 @@ class NoMatchFound(Exception):
     if no matching route exists.
     """
 
+    def __init__(self, name: str, path_params: typing.Dict[str, typing.Any]) -> None:
+        params = ", ".join(list(path_params.keys()))
+        super().__init__(f'No route exists for name "{name}" and params "{params}".')
+
 
 class Match(Enum):
     NONE = 0
@@ -240,7 +244,7 @@ class Route(BaseRoute):
         expected_params = set(self.param_convertors.keys())
 
         if name != self.name or seen_params != expected_params:
-            raise NoMatchFound()
+            raise NoMatchFound(name, path_params)
 
         path, remaining_params = replace_params(
             self.path_format, self.param_convertors, path_params
@@ -309,7 +313,7 @@ class WebSocketRoute(BaseRoute):
         expected_params = set(self.param_convertors.keys())
 
         if name != self.name or seen_params != expected_params:
-            raise NoMatchFound()
+            raise NoMatchFound(name, path_params)
 
         path, remaining_params = replace_params(
             self.path_format, self.param_convertors, path_params
@@ -408,7 +412,7 @@ class Mount(BaseRoute):
                     )
                 except NoMatchFound:
                     pass
-        raise NoMatchFound()
+        raise NoMatchFound(name, path_params)
 
     async def handle(self, scope: Scope, receive: Receive, send: Send) -> None:
         await self.app(scope, receive, send)
@@ -472,7 +476,7 @@ class Host(BaseRoute):
                     return URLPath(path=str(url), protocol=url.protocol, host=host)
                 except NoMatchFound:
                     pass
-        raise NoMatchFound()
+        raise NoMatchFound(name, path_params)
 
     async def handle(self, scope: Scope, receive: Receive, send: Send) -> None:
         await self.app(scope, receive, send)
@@ -593,7 +597,7 @@ class Router:
                 return route.url_path_for(name, **path_params)
             except NoMatchFound:
                 pass
-        raise NoMatchFound()
+        raise NoMatchFound(name, path_params)
 
     async def startup(self) -> None:
         """
index acd7cdb267c3956d0a8e75bc2c6b9cb83e42a89e..7077c5616befbacca7139a6debeefeb4d6be611f 100644 (file)
@@ -243,8 +243,14 @@ def test_url_path_for():
     assert app.url_path_for("homepage") == "/"
     assert app.url_path_for("user", username="tomchristie") == "/users/tomchristie"
     assert app.url_path_for("websocket_endpoint") == "/ws"
-    with pytest.raises(NoMatchFound):
+    with pytest.raises(
+        NoMatchFound, match='No route exists for name "broken" and params "".'
+    ):
         assert app.url_path_for("broken")
+    with pytest.raises(
+        NoMatchFound, match='No route exists for name "broken" and params "key, key2".'
+    ):
+        assert app.url_path_for("broken", key="value", key2="value2")
     with pytest.raises(AssertionError):
         app.url_path_for("user", username="tom/christie")
     with pytest.raises(AssertionError):