New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeError when connection is closed in connect() #244
Comments
I'm also facing this issue - when connections are closed, several errors pop up. Doesn't affect operation, but quite concerning nonetheless. Full stack trace (may be mixed with other errs...):
|
Still facing this issue. |
Okay - can someone break this issue down to something smaller, not involving channels. (Use |
Hi, I think we have the same problem in our app:
|
@sergicolladosopra Okay, with Channels or something else? What's the smallest possible codebase someone can reduce this down too, so that I've got a good place to start digging from? |
Here is a minimal example without using django: class Application:
def __init__(self, scope):
self.scope = scope
async def __call__(self, receive, send):
if self.scope["type"] != "websocket":
return
while True:
# what for the 'websocket.connect' event.
await receive()
# Close the connection
await send({'type': 'websocket.close'}) To test it, you have to start it with an asgi server an open a websocket connection. With daphne:
With uvicorn and websockets:
With uvicorn and wsproto:
The error seems to be, that the The loop in django channels is here: https://github.com/django/channels/blob/03d221792e6881477911728615a6d51ec9fab73b/channels/utils.py#L45 The An exception, that could break the loop is raised when |
Channels allows to call I took a look into
and seems like it's implemented on the web servers and maybe also in channels' middlewares. So calling close() when connection handshaking is not a right thing to do? |
I also have this issue, using uvicorn 0.8.6 and channels 2.2.0. My channels consumers don't call In
At that point,
The
I also see this:
I tested on Linux (WSL) and I get basically the same traceback. Happy to provide any additional info to troubleshoot this. |
The thing that would help most with progressing this would be to try to replicate the issue in a plain ASGI application, or in Starlette, or something more minimal than installing Channels. If anyone's able to reduce the issue like that then I'd be very happy to dig into it. |
|
Is there any update or workaround for this? I can post more info about what I'm seeing, but it looks like the connection closes and things are fine browser side, but if I call .close() in the .connect() function I end up with type errors in the logs. Having stack traces in the logs is obviously not ideal, but it would help to clarify that's the extent of the issue... |
My workaround is to open the connection and close it immediately. |
Fixes encode#244. The unit test already existed, but it logged exceptions that weren't being noticed. * websockets_impl: `transfer_data_task` is unset if the handshake fails, so we can't call recv(). * wsproto_impl: `h11.Reject` is invalid during handshake; send `RejectConnection` instead.
Turns out this error was being logged -- and ignored -- in the unit-test suite already. I'm not 100% confident in my reading of the ASGI-to-websockets spec. The Websockets spec (as cited in the For all I know, all real-world ASGI applications call |
Fixes encode#244. The unit test already existed, but it logged exceptions that weren't being noticed. * websockets_impl: `transfer_data_task` is unset if the handshake fails, so we can't call recv(). * wsproto_impl: `h11.Reject` is invalid during handshake; send `RejectConnection` instead.
@tomchristie ping? I have reduced the issue by enabling logging in Uvicorn's own test suite. I also submitted pull request #704 with a sketch of a fix. Are you still keen to dig into it? :) |
Is there any way at all I can be of any more help? I've helped diagnose, I've authored a pull request, I've written helpful notes on all issues I could find that seemed relevant. I'm doing my best, and I'm prepared to do better. Please direct me. Our project experiences this stack trace >35,000 times per day. I worry that real, as-yet unknown errors are hiding among all those duplicates. |
This has been the only way so far to silence the uvicorn errors we are seeing. |
Hi all, I'm taking a look at this given pings on #704. I was able to reproduce the async def app(scope, receive, send):
assert scope["type"] == "websocket"
# Pull up first recv message.
message = await receive()
assert message["type"] == "websocket.connect"
# Reject the connection.
await send({"type": "websocket.close"})
# -- At this point websockets' recv() is unusable. --
# This raises the `TypeError` on the server.
message = await receive()
# But we would expect it to succeed and return this:
assert message["type"] == "websocket.disconnect" Client: $ python -m asyncio
>>> import websockets
>>> await websockets.connect("ws://localhost:8000")
websockets.exceptions.InvalidStatusCode: server rejected WebSocket connection: HTTP 403 The client sees the 403 after we sent |
maybe this is relevant too: |
[closes encode#244] Previously, if the application tried to close the connection before the handshake completed, uvicorn would log: TypeError: An asyncio.Future, a coroutine or an awaitable is required. These TypeErrors happen in tests/protocols/test_websocket.py. pytest is hiding them. In my initial pull request, I added `caplog` to `test_websocket.py` to expose the bug: def test_close_connection(protocol_cls, caplog): caplog.set_level(logging.ERROR) # ... assert not [r.message for r in caplog.records] ... but this caused unrelated errors on Windows; so @florimondmanca suggests leaving the test suite alone, in encode#704 (comment)
[closes #244] Previously, if the application tried to close the connection before the handshake completed, uvicorn would log: TypeError: An asyncio.Future, a coroutine or an awaitable is required. These TypeErrors happen in tests/protocols/test_websocket.py. pytest is hiding them. In my initial pull request, I added `caplog` to `test_websocket.py` to expose the bug: def test_close_connection(protocol_cls, caplog): caplog.set_level(logging.ERROR) # ... assert not [r.message for r in caplog.records] ... but this caused unrelated errors on Windows; so @florimondmanca suggests leaving the test suite alone, in #704 (comment)
I have the same problem then #185 but I think, I can reproduce it.
When you close a connection in the connect() method of a WebsocketConsumer, it works fine with daphne but uvicorn raises a TypeError
I created this branch on the django-channels-example repository: https://github.com/ostcar/channels-examples/tree/uvicorn-test
All I changed was, that the websocket connection is always closed: andrewgodwin/channels-examples@master...ostcar:uvicorn-test
I think the problem is, that you call
websockets.WebSocketServerProtocol.recv()
before the websocket connection is open sowebsockets.WebSocketServerProtocol.connection_open()
was not called. In this case the attributetransfer_data_task
is still None. So whenwebsockets.WebSocketServerProtocol.recv()
callsit tries to await
None
what causes the exception.I don't know, if this is a but in the websockets package or if you should check
self.closed
before callingself.recv()
The text was updated successfully, but these errors were encountered: