handleUndecodable method
Called for an incoming data frame this session could not read.
Covers a frame no codec claimed and one that threw on the way in. The default reports a SessionEventType.error event and answers the peer with Protocol.errorInvalidMessage: a client that hears nothing back cannot tell a rejected frame from a slow one, and waits for a reply that is never coming. Sessions may override it to say something more precise first (a relay session diagnoses a CRDT-aware sync client that connected to the wrong server).
Implementation
@override
void handleUndecodable(List<int> data) {
final type = Message.getTypeOrNull(data);
// Core-protocol frames (below the relay range) reaching a relay server are
// almost always a CRDT-aware sync client connected to the wrong server.
// The relay does not decode them (they carry no relay semantics), so they
// surface here as undecodable — answer with a diagnostic instead of a
// silent drop. Ping/pong/error decode fine and never reach this path.
if (type != null && type < RelayMessageType.relayHello.value) {
// Logged as well as answered: the operator of the relay is the one who
// can tell the client it connected to the wrong server, and a reply that
// leaves no trace here says nothing to them.
addSessionEvent(
SessionEventGeneric(
sessionId: id,
type: SessionEventType.error,
message: 'Refused a CRDT-aware sync frame (type $type): '
'this server runs the relay protocol.',
),
);
unawaited(
sendMessage(
Message.error(
// Names no document: see ClientSession.handleUndecodable.
documentId: '',
code: Protocol.errorInvalidMessage,
message: 'This server runs the relay protocol: '
'the CRDT-aware sync protocol is not supported. '
'Connect with a relay client.',
),
),
);
return;
}
super.handleUndecodable(data);
}