handleUndecodable method

  1. @override
void handleUndecodable(
  1. List<int> data
)
override

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);
}