When a permissions class's has_permission
method returns False for a subscription, strawberry subsequently throws some errors while closing the connection.
When a subscription fails due to an authentication failure, we see log outputs that look like this
< TEXT '{"type":"connection_init","payload":{"Authoriza...bGt1hupQ9QVf1VYivKHw"}}' [844 bytes]
> TEXT '{"type": "connection_ack"}' [26 bytes]
< TEXT '{"id":"5","type":"start","payload":{"variables"...ypename\\n }\\n}\\n"}}' [3034 bytes]
> TEXT '{"type": "error", "id": "5", "payload": {"messa...buildingDataChanges"]}}' [144 bytes]
Not Authorized
GraphQL request:2:3
...
raise PermissionError(message)
PermissionError: Not Authorized
< TEXT '{"id":"5","type":"stop"}' [24 bytes]
Exception in ASGI application
Traceback (most recent call last):
...
File ".../strawberry/subscriptions/protocols/graphql_ws/handlers.py", line 193, in cleanup_operation
await self.subscriptions[operation_id].aclose()
KeyError: '5'
= connection is CLOSING
> CLOSE 1000 (OK) [2 bytes]
= connection is CLOSED
! failing connection with code 1006
closing handshake failed
Traceback (most recent call last):
...
File ".../websockets/legacy/protocol.py", line 935, in ensure_open
raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: sent 1000 (OK); no close frame received
connection closed
This seems to indicate that the permissions failure prevents the subscription from being created, which causes cleanup to fail since it assumes the subscription exists. If I modify
to check foroperation_id
in self.subscriptions
and self.tasks
before accessing them, then both the KeyError
and closing handshake failed
errors go away.
Since an expired token can cause rapid subscription retries and failures, this can produce quite a lot of log spam.
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too