diff --git a/packages/socket.io-client/lib/socket.ts b/packages/socket.io-client/lib/socket.ts index a1713a187b..1dc3239afa 100644 --- a/packages/socket.io-client/lib/socket.ts +++ b/packages/socket.io-client/lib/socket.ts @@ -111,9 +111,11 @@ export type DisconnectDescription = context?: unknown; // context should be typed as CloseEvent | XMLHttpRequest, but these types are not available on non-browser platforms }; +type ConnectError = Error & { data?: any }; + interface SocketReservedEvents { connect: () => void; - connect_error: (err: Error) => void; + connect_error: (err: ConnectError) => void; disconnect: ( reason: Socket.DisconnectReason, description?: DisconnectDescription, @@ -734,8 +736,7 @@ export class Socket< case PacketType.CONNECT_ERROR: this.destroy(); - const err = new Error(packet.data.message); - // @ts-ignore + const err: ConnectError = new Error(packet.data.message); err.data = packet.data.data; this.emitReserved("connect_error", err); break; diff --git a/packages/socket.io-client/test/socket.ts b/packages/socket.io-client/test/socket.ts index 9374453850..6cdf8188c7 100644 --- a/packages/socket.io-client/test/socket.ts +++ b/packages/socket.io-client/test/socket.ts @@ -286,6 +286,17 @@ describe("socket", () => { }); }); + it("should forward the data attached to a middleware error", () => { + return wrap((done) => { + const socket = io(BASE_URL + "/no-with-data", { forceNew: true }); + socket.on("connect_error", (err) => { + expect(err.data).to.eql({ code: "UNAUTHORIZED" }); + socket.disconnect(); + done(); + }); + }); + }); + it("should not try to reconnect after a middleware failure", () => { return wrap((done) => { const socket = io(BASE_URL + "/no", { diff --git a/packages/socket.io-client/test/support/server.ts b/packages/socket.io-client/test/support/server.ts index 3003a6fea9..1a7f13736b 100644 --- a/packages/socket.io-client/test/support/server.ts +++ b/packages/socket.io-client/test/support/server.ts @@ -1,4 +1,4 @@ -import { Server } from "socket.io"; +import { ExtendedError, Server } from "socket.io"; import expect = require("expect.js"); export function createServer() { @@ -44,6 +44,12 @@ export function createServer() { next(new Error("Auth failed (custom namespace)")); }); + server.of("/no-with-data").use((socket, next) => { + const err: ExtendedError = new Error("Auth failed (with data)"); + err.data = { code: "UNAUTHORIZED" }; + next(err); + }); + server.on("connection", (socket) => { // simple test socket.on("hi", () => { diff --git a/packages/socket.io-client/test/typed-events.test-d.ts b/packages/socket.io-client/test/typed-events.test-d.ts index d7e56de46d..0f4efdf657 100644 --- a/packages/socket.io-client/test/typed-events.test-d.ts +++ b/packages/socket.io-client/test/typed-events.test-d.ts @@ -26,7 +26,7 @@ describe("typed events", () => { expectError(socket.on("connect", (arg) => {})); socket.on("connect_error", (err) => { - expectType(err); + expectType(err); }); socket.on("disconnect", (reason) => {