Skip to content

Commit

Permalink
Display missing route details. (#1363)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
3 people committed Feb 14, 2022
1 parent 3f6d4f5 commit 93ad0b9
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
14 changes: 9 additions & 5 deletions starlette/routing.py
Expand Up @@ -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
Expand Down Expand Up @@ -240,7 +244,7 @@ def url_path_for(self, name: str, **path_params: typing.Any) -> URLPath:
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
Expand Down Expand Up @@ -309,7 +313,7 @@ def url_path_for(self, name: str, **path_params: typing.Any) -> URLPath:
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
Expand Down Expand Up @@ -408,7 +412,7 @@ def url_path_for(self, name: str, **path_params: typing.Any) -> URLPath:
)
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)
Expand Down Expand Up @@ -472,7 +476,7 @@ def url_path_for(self, name: str, **path_params: typing.Any) -> URLPath:
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)
Expand Down Expand Up @@ -593,7 +597,7 @@ def url_path_for(self, name: str, **path_params: typing.Any) -> URLPath:
return route.url_path_for(name, **path_params)
except NoMatchFound:
pass
raise NoMatchFound()
raise NoMatchFound(name, path_params)

async def startup(self) -> None:
"""
Expand Down
8 changes: 7 additions & 1 deletion tests/test_routing.py
Expand Up @@ -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):
Expand Down

0 comments on commit 93ad0b9

Please sign in to comment.