forwardemail / forwardemail/supertest

Launching a server on-the-fly can intermittently cause failures due to asynchronous startup

Open
#566 0 comments 16 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
14.4k
Forks
782
PR merge metrics
No merged PRs in 30d

Description

[`Server.listen` is *asynchronous* with a callback parameter](https://nodejs.org/api/net.html#net_server_listen), but [this line](https://github.com/visionmedia/supertest/blob/master/lib/test.js#L48) invokes it as a synchronous operation (or fire-and-forget).

This is usually fine, as the server address is set immediately and by the time a request first reaches the server, it has usually started up. But it is a race condition, and I have noticed tests in my project occasionally fail because of it.

The fix is to start the server in advance, for example:

```javascript
describe('whatever', () => {
let server;

beforeEach((done) => {
server = app.listen(0, done); // expressjs (syntax is similar for raw http.Server)
});

afterEach(() => {
server.close();
});

it('something', async () => {
await request(server)
.get('/woo')
.expect(200);
});
});
```

This also allows closing the server at the end; something which supertest does not do if it launches a server on request (see e.g. https://github.com/visionmedia/supertest/issues/489 and https://github.com/visionmedia/supertest/issues/437)

This issue can be worked around by adding special logic to internally wait for the `listen` to succeed before sending any requests, but this will add a fair amount of complexity to the code. I suggest the better fix is to drop this feature and encourage all users of the library to write tests as shown above; with an externally-managed server lifecycle. The user can wait until it has fully started up and is aware of when the server can be shutdown; supertest doesn't have all this information so shouldn't try to half-way infer it.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.