question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Return 404 for invalid routes

See original GitHub issue

Currently, any request which doesn’t match a route causes an error-level log event. HTTP requests are mapped to the usual Django 404 path but websockets cause a traceback like this:

$ pipenv run daphne -p 8001 inventory.asgi:application
Loading .env environment variables…
[2018-02-07 20:04:12] botocore.credentials INFO Found credentials in shared credentials file: ~/.aws/credentials
[2018-02-07 20:04:12] daphne.cli INFO Starting server at tcp:port=8001:interface=127.0.0.1
[2018-02-07 20:04:12] daphne.server INFO HTTP/2 support not enabled (install the http2 and tls Twisted extras)
[2018-02-07 20:04:12] daphne.server INFO Listening on endpoint tcp:port=8001:interface=127.0.0.1
[2018-02-07 20:04:28] daphne.ws_protocol ERROR Traceback (most recent call last):
  File "/Users/cadams/.virtualenvs/inventory-api-prototype-yJheR8NE/lib/python3.6/site-packages/daphne/ws_protocol.py", line 76, in onConnect
    "subprotocols": subprotocols,
  File "/Users/cadams/.virtualenvs/inventory-api-prototype-yJheR8NE/lib/python3.6/site-packages/daphne/server.py", line 177, in create_application
    application_instance = self.application(scope=scope)
  File "/Users/cadams/.virtualenvs/inventory-api-prototype-yJheR8NE/lib/python3.6/site-packages/channels/routing.py", line 51, in __call__
    return self.application_mapping[scope["type"]](scope)
  File "/Users/cadams/.virtualenvs/inventory-api-prototype-yJheR8NE/lib/python3.6/site-packages/channels/routing.py", line 89, in __call__
    raise ValueError("No route found for path %r." % path)
ValueError: No route found for path 'foo/bar'.
$ wst client ws://localhost:8001/foo/bar
Client closed connection (Abnormal) 

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

4reactions
bocyncommented, Mar 26, 2021

I’ve end up with below code:

middleware.py


class RouteNotFoundMiddleware:
    def __init__(self, app):
        self.app = app

    async def __call__(self, scope, receive, send):
        try:
            return await self.app(scope, receive, send)
        except ValueError as e:
            if (
                "No route found for path" in str(e)
                and scope["type"] == "websocket"
            ):
                await send({"type": "websocket.close"})
                logger.warning(e)
            else:
                raise e

asgi.py


application = ProtocolTypeRouter(
    {
        "http": get_asgi_application(),
        "websocket": AuthMiddlewareStack(
            RouteNotFoundMiddleware(
                URLRouter(ws.routing.websocket_urlpatterns)
            )
        )
    }
)

My environment:

Python 3.8.6 django 3.1.7 channels 3.0.3 daphne 3.0.1

2reactions
lambdaTWcommented, Jan 26, 2020

@acdha I got this issue from sentry many times, so I write middleware for handling it. I hope it’s the right way to handle this problem If any good idea please let me know, thanks.

from datetime import datetime
from logging import getLogger
from django.urls.exceptions import Resolver404


logger = getLogger(__file__)


class HandleRouteNotFoundMiddleware:

    def __init__(self, inner):
        self.inner = inner

    def __call__(self, scope):
        try:
            inner_instance = self.inner(scope)
            return inner_instance 
        except (Resolver404, ValueError) as e:
            if 'No route found for path' not in str(e) and \
               scope["type"] not in ['http', 'websocket']:
                raise e

            logger.warning(
                f'{datetime.now()} - {e} - {scope}'
            )

            if scope["type"] == "http":
                return self.handle_http_route_error
            elif scope["type"] == "websocket":
                return self.handle_ws_route_error

    async def handle_ws_route_error(self, receive, send):
        await send({"type": "websocket.close"})

    async def handle_http_route_error(self, receive, send):
        await send({
            "type": "http.response.start",
                    "status": 404,
                    "headers": {},
        })
        await send({
            "type": "http.response.body",
            "body": "",
            "more_body": "",
        })

from core.middleware import HandleRouteNotFoundMiddleware


application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        HandleRouteNotFoundMiddleware(
            URLRouter(
                routing.websocket_urlpatterns
            )
        )
    ),
    'channel': router,
    'http': HandleRouteNotFoundMiddleware(
        URLRouter(
            urlpatterns
        )
    )
})
Read more comments on GitHub >

github_iconTop Results From Across the Web

Return 404 for invalid routes via nginx
In that case i want to throw 404 without landing to application at nginx level itself. Is this possible to handle routing at...
Read more >
How To Properly Serve 404 Errors on SPAs (with SEO ...
Out of the box, 404 error pages in SPAs don't work properly, creating problems for SEO. Here we'll review the pros and cons...
Read more >
Handling 404 Not Found in Asp.Net Core - DevTrends
This is where the URL matches a route but one or more parameter is invalid. We can address this with a custom view....
Read more >
How to wrap a route not found exception with the generic ...
The status code 404 is also added to the response when the resource is not found, like when Id is not found or...
Read more >
404 page instead of {METHOD} not supported for this route
It sounds like the order of your routes might cause this. If you have for example first a route 'products/{product}' followed by a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found