Emit a single disconnected event when connecting fails#1126
Conversation
| events.emit(EngineDisconnectedEvent( | ||
| reason: DisconnectReason.joinFailure, | ||
| reason: error is CertificatePinningException | ||
| ? DisconnectReason.signalingConnectionFailure | ||
| : DisconnectReason.joinFailure, | ||
| )); |
There was a problem hiding this comment.
🔍 Region fallback in Room.connect may emit a spurious RoomDisconnectedEvent before retrying
When Room.connect catches a WebSocketException or ConnectException from the first engine.connect call and falls back to a regional URL (room.dart:340-366), the engine's catch block at lib/src/core/engine.dart:271-275 has already emitted an EngineDisconnectedEvent. The room's listener at lib/src/core/room.dart:596-601 converts this into a RoomDisconnectedEvent. If the second engine.connect succeeds, the room ends up having emitted a disconnect event followed by a successful connection — which could confuse listeners. This is a pre-existing issue not introduced by this PR, but since the PR's goal is to ensure a single disconnected event per failure, it may be worth addressing in a follow-up.
Was this helpful? React with 👍 or 👎 to provide feedback.
c260cba to
11a9f0f
Compare
Summary
Follow-up to #1065. Ensures the SDK emits exactly one
RoomDisconnectedEventper failed connection attempt.Previously a failed initial connect produced two
EngineDisconnectedEvents, and therefore twoRoomDisconnectedEvents and two room cleanups:SignalDisconnectedEvent(signalingConnectionFailure)whileconnect()is failing (the validate path has done this since Improve reconnect logic for websocket #406, and the certificate pinning path in Certificate pinning #1065 follows the same pattern), which the engine relayed asEngineDisconnectedEvent.Engine.connect's catch then emitsEngineDisconnectedEvent(joinFailure)for the same failure.Changes
Engine.connect's catch is now the single emitter for initial connect failures. It picks the reason by error type:signalingConnectionFailureforCertificatePinningException,joinFailureotherwise.signalingConnectionFailurerelay in the engine's signal listener is removed (with a comment explaining why). During reconnects the engine's reconnect handling already owns disconnect emission, so the relay only ever produced duplicates. This also removes the_isReconnecting/_attemptingReconnectguard that Certificate pinning #1065 added to suppress the relay during reconnects, since there is no longer anything to suppress.SignalDisconnectedEventat the signal level is unchanged, only the engine-level relay is removed.Behavior change
Apps listening for
RoomDisconnectedEventnow receive one event per failed connect instead of two. The reasons are unchanged for the common case (joinFailure); certificate pinning failures surface assignalingConnectionFailure. Apps that specifically depended on receiving both events for a single failure would see one.Testing
Added room-level tests through the mock e2e container asserting exactly one
RoomDisconnectedEventper failed initial connect, for both a certificate pinning failure (signalingConnectionFailure) and a generic websocket failure (joinFailure). Both tests fail against the previous code (two events observed) and pass with this change.