diff --git a/lib/socket.ts b/lib/socket.ts index 3deb8c413..afa567e3a 100644 --- a/lib/socket.ts +++ b/lib/socket.ts @@ -84,6 +84,7 @@ export class Socket extends Emitter { this.subs = [ on(io, "open", this.onopen.bind(this)), on(io, "packet", this.onpacket.bind(this)), + on(io, "error", this.onerror.bind(this)), on(io, "close", this.onclose.bind(this)), ]; } @@ -204,6 +205,18 @@ export class Socket extends Emitter { } } + /** + * Called upon engine or manager `error`. + * + * @param err + * @private + */ + private onerror(err: Error) { + if (!this.connected) { + super.emit("connect_error", err); + } + } + /** * Called upon engine `close`. * diff --git a/test/socket.ts b/test/socket.ts index b27be71d5..263404143 100644 --- a/test/socket.ts +++ b/test/socket.ts @@ -50,6 +50,31 @@ describe("socket", function () { }, 300); }); + it("fire a connect_error event when the connection cannot be established", (done) => { + const socket = io("http://localhost:9823", { + forceNew: true, + timeout: 100, + }); + socket.on("connect_error", () => { + socket.close(); + done(); + }); + }); + + it("doesn't fire a connect_error event when the connection is already established", (done) => { + const socket = io({ forceNew: true }); + socket.on("connect", () => { + socket.io.engine.close(true); + }); + socket.on("connect_error", () => { + done(new Error("should not happen")); + }); + setTimeout(() => { + socket.close(); + done(); + }, 300); + }); + it("should change socket.id upon reconnection", (done) => { const socket = io({ forceNew: true }); socket.on("connect", () => {