Skip to content

Commit

Permalink
fix: ignore packets when the transport is silently closed
Browse files Browse the repository at this point in the history
In some cases, a "Transport not open" error could be thrown when the
transport was silently closed in the onbeforeunload event (added in
[1]).

To reproduce:

```js
window.addEventListener("unload", () => {
  socket.write("...");
});
```

[1]: ed48b5d

Related: socketio/socket.io#3838
  • Loading branch information
darrachequesne committed Mar 31, 2021
1 parent fc5dc6b commit d291a4c
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
4 changes: 3 additions & 1 deletion lib/transport.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const parser = require("engine.io-parser");
const Emitter = require("component-emitter");
const debug = require("debug")("engine.io-client:transport");

class Transport extends Emitter {
/**
Expand Down Expand Up @@ -70,7 +71,8 @@ class Transport extends Emitter {
if ("open" === this.readyState) {
this.write(packets);
} else {
throw new Error("Transport not open");
// this might happen if the transport was silently closed in the beforeunload event handler
debug("transport is not open, discarding packets");
}
}

Expand Down
30 changes: 30 additions & 0 deletions test/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,34 @@ describe("connection", function() {
});
});
}

if (env.browser && typeof addEventListener === "function") {
it("should close the socket when receiving a beforeunload event", done => {
const socket = new Socket();

const createEvent = name => {
if (typeof Event === "function") {
return new Event(name);
} else {
// polyfill for IE
const event = document.createEvent("Event");
event.initEvent(name, true, true);
return event;
}
};

socket.on("open", () => {
const handler = () => {
expect(socket.transport.readyState).to.eql("closed");
expect(() => socket.write("ignored")).to.not.throwException();

removeEventListener("beforeunload", handler, false);
done();
};

addEventListener("beforeunload", handler, false);
dispatchEvent(createEvent("beforeunload"));
});
});
}
});

0 comments on commit d291a4c

Please sign in to comment.