Repository: sanic-org/sanic

Issue:
[Feature Request] Warn when multiple route names are the same
**Is your feature request related to a problem? Please describe your use case.**
Just spent a good amount of time trying to figure why injections were not working on certain routes, after digging the code a bit more, it seemed like when the route names are the same, the injection will overwrite the value in the `SignatureRegistry`

**Describe the solution you'd like**
Something like this, showing which route names are already in the registry and maybe also mentioning which route have injections (although that last one would be for debugging purposes, maybe have a toggle?):

```py
[2022-08-08 21:17:46 -0400] [80724] [DEBUG] Dispatching signal: server.init.after
[2022-08-08 21:23:19 -0400] [81202] [DEBUG] Injecting into route 'manager.cases.get_cases' {'user': (<class 'src.utils.User'>, <Constructor(func=create)>)} 
[2022-08-08 21:23:19 -0400] [81202] [WARNING] Following route has already been injected: 'ioc_manager.templates.get_rule_filters'
[2022-08-08 21:23:19 -0400] [81202] [WARNING] Following route has already been injected: 'ioc_manager.cases.get_case_iocs'
[2022-08-08 21:23:19 -0400] [81202] [WARNING] Following route has already been injected: 'ioc_manager.cases.get_case_iocs'
[2022-08-08 21:17:46 -0400] [80724] [INFO] Starting worker [80724]
```

For the warning, I've just added a simple check here:

https://github.com/sanic-org/sanic-ext/blob/b65cd9f28c8d1e6ee0aad91685bfb84fc4925ac6/sanic_ext/extensions/injection/registry.py#L54-L59

With

```py
    def register(
        self,
        route_name: str,
        injections: Dict[str, Tuple[Type, Optional[Callable[..., Any]]]],
    ) -> None:
        if route_name in self._registry:
            logger.warning(f"Following route has already been injected: '{route_name}'")
        self._registry[route_name] = injections
```


Discussion:
Not sure if this should be a part of `sanic_ext` or `sanic`
Another way would be to list, at the beginning when starting the server, all the routes and their route names, and then warning on the duplicate ones (I would personally love this since you sometimes don't know which routes/handlers _actually_ get registered when you have a big codebase with nested blueprints) - unless that's already a feature
This is a known thing. We will probably start with a warning and eventually raise an error for duplicate named routes. It will probably be a part of `sanic-routing` in `finalize`.
I am going to solve this in app startup so we can provide a deprecation notice consistently.

Resolving patch:
diff --git a/sanic/app.py b/sanic/app.py
--- a/sanic/app.py
+++ b/sanic/app.py
@@ -1521,6 +1521,18 @@ async def _startup(self):
         self.signalize(self.config.TOUCHUP)
         self.finalize()
 
+        route_names = [route.name for route in self.router.routes]
+        duplicates = {
+            name for name in route_names if route_names.count(name) > 1
+        }
+        if duplicates:
+            names = ", ".join(duplicates)
+            deprecation(
+                f"Duplicate route names detected: {names}. In the future, "
+                "Sanic will enforce uniqueness in route naming.",
+                23.3,
+            )
+
         # TODO: Replace in v22.6 to check against apps in app registry
         if (
             self.__class__._uvloop_setting is not None


Test patch:
diff --git a/tests/test_routes.py b/tests/test_routes.py
--- a/tests/test_routes.py
+++ b/tests/test_routes.py
@@ -1266,3 +1266,22 @@ async def handler(request: Request):
 
     assert request.route.ctx.foo() == "foo"
     assert await request.route.ctx.bar() == 99
+
+
+@pytest.mark.asyncio
+async def test_duplicate_route_deprecation(app):
+    @app.route("/foo", name="duped")
+    async def handler_foo(request):
+        return text("...")
+
+    @app.route("/bar", name="duped")
+    async def handler_bar(request):
+        return text("...")
+
+    message = (
+        r"\[DEPRECATION v23\.3\] Duplicate route names detected: "
+        r"test_duplicate_route_deprecation\.duped\. In the future, "
+        r"Sanic will enforce uniqueness in route naming\."
+    )
+    with pytest.warns(DeprecationWarning, match=message):
+        await app._startup()