Closed DrPyser closed 5 days ago
Short term mitigation: check out the changelog for an explanation of what's happening and how to get the previous behavior back; the legacy implementation will be maintained for five years.
That being said, the new implementation of connect is documented to raise InvalidHandshake
(which InvalidMessage
inherits) but not EOFError
.
Options include:
EOFError
can be raised: it's a reasonable exception when you don't get a single byte from a connection. That case isn't really an InvalidHandsake
; it's an absence of handshake.EOFError
and re-raising InvalidHandshake
.ClientConnection.handshake()
raises raise self.protocol.handshake_exc
. As a consequence, connect()
can raise any exception saved in handshake_exc
.
There are two places where handshake_exc
is assigned. One of them is in a except InvalidHandshake as exc:
block so it's fine. The other one is in a except Exception as exc:
and it's the problem here. It catches exception raised by yield from Response.parse(...)
and there's many of them (EOFError
, SecurityError
, LookupError
, ValueError
). It makes sense to wrap them in an InvalidHandshake
exception.
In this scenario, the legacy implementation did:
try:
status_code, reason, headers = await read_response(self.reader)
except Exception as exc:
raise InvalidMessage("did not receive a valid HTTP response") from exc
The new implementation doesn't use InvalidMessage
anywhere; that exception was deprecated together with the legacy implementation. So we have a choice between:
InvalidHandshake
I'm leaning towards bringing back InvalidMessage
.
So -
websockets<14.0
or import websockets.legacy.client.connect
, whichever you like best.@aaugustin Thank you for your quick response and detailed breakdown.
I think in our case we're fine with catching EOFError
in the relevant code, instead of binding ourselves to the legacy implementation. We'll be on the lookout if you revert back the exception handling.
Yes that works too!
I started a PR. It requires adjusting tests and adding a changelog.
Some of our automated tests using
websockets
started failing since the upgrade of test client code to websockets 14.0.The code in question is attempting connections to a server that might not be ready to handle connections yet, and previously we expected exceptions
ConnectionClosed
orInvalidMessage
fromwebsockets.connect
, but now we're gettingEOFError
(response parsing errors) instead.ref. (the relevant test code) https://github.com/wazo-platform/wazo-websocketd/blob/de1531769a81bb90a99395371ad8b1da6a745dd5/integration_tests/suite/helpers/wait_strategy.py#L38-L45 https://github.com/wazo-platform/wazo-websocketd/blob/de1531769a81bb90a99395371ad8b1da6a745dd5/integration_tests/suite/helpers/websocketd.py#L41
(the failing test run) https://jenkins.wazo.community/job/integration-tests-nolock/742//console
From the failing test logs: