Skip to content
15 changes: 10 additions & 5 deletions starlette/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class NoMatchFound(Exception):
if no matching route exists.
"""

def __init__(self, name: str, path_params: typing.Dict[str, typing.Any]) -> None:
super().__init__(
f'No route exists for name "{name}" and params "{path_params}".'
Comment thread
Kludex marked this conversation as resolved.
Outdated
)


class Match(Enum):
NONE = 0
Expand Down Expand Up @@ -240,7 +245,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 @@ -306,7 +311,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 @@ -405,7 +410,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 @@ -469,7 +474,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 @@ -590,7 +595,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
4 changes: 3 additions & 1 deletion tests/test_routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@ 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(AssertionError):
app.url_path_for("user", username="tom/christie")
Expand Down