Skip to content

PacketType.CONNECT_ERROR adds err.data but downstream interface SocketReservedEventsMap does not expect that #5542

Description

@jml6m

Describe the bug
The connect_error event callback argument is typed as standard JavaScript Error in SocketReservedEventsMap. As a result, accessing err.data in any downstream function produces a compiler error (Property 'data' does not exist on type 'Error'), even though err.data is used on the onpacket function in socket.io-client/lib/socket.ts.

Also, the PacketType.CONNECT_ERROR case relies on a // @ts-ignore to attach packet.data.data to the Error instance, which is not best practice.

To Reproduce

Socket.IO server version: 4.7.5 (or any v4.x)

Server

import { Server } from "socket.io";

// Creates the server and binds it to port 3000 automatically
const io = new Server(3000, {
  cors: {
    origin: "*" // Essential if testing from a browser app or a different origin
  }
});

interface ExtendedError extends Error {
  data?: any;
}

// Blocks every connection with your error payload
io.use((socket, next) => {
  // ExtendedError required here, or @ts-ignore the `err.data` assignment
  const err = new Error("not authorized") as ExtendedError;
  err.data = "some data"

  // Also note that code in /packages/socket.io-client/lib/socket.ts assumes a message as well
  // err.message = "Retry later"

  next(err);
});

console.log("Standalone Socket.IO server running on port 3000");

Socket.IO client version: 4.7.5 (or any v4.x)

Client

import { io } from "socket.io-client";

const socket = io('http://localhost:3000');

socket.on("connect_error", (err) => {
  // TypeScript error: Property 'data' does not exist on type 'Error'.
  console.log(err.data);
});

Expected behavior

export interface SocketReservedEventsMap {
  connect_error: (err: Error) => void;
}

The argument in connect_error above should be typed with an interface that includes data, and likely extends Error (unless a more creative solution is found), matching the expectations expressed in the official Socket.IO documentation and removing the need for any downstream consumer casts ((err as any).data) and/or the internal // @ts-ignore in socket.ts.

Platform:

  • Device: Any
  • OS: Any
  • TypeScript: 5.x

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    to triageWaiting to be triaged by a member of the team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions