fix: Standalone node http server starts accepting requests before next handler is ready (#49548)
### Fixing a bug
Fixes #49536
Fixes #49338
### What?
Starting on next.js 13.4.0, the `server.js` file created by the
standalone output is incorrect because it does not wait until the Next
handler is ready before node http server starts accepting requests.
Initial requests will produce the following error:
```
TypeError: handler is not a function
at Server.<anonymous> (/tmp/app/server.js:29:11)
at Server.emit (node:events:513:28)
at parserOnIncoming (node:_http_server:998:12)
at HTTPParser.parserOnHeadersComplete (node:_http_common:128:17)
```
### Why?
The creation of the next server takes roughly 800ms on a basic hello
world app which causes the initial requests to fail because the
`handler` variable is not initialized.
### Solution
This changes the order of code so that Next Server is initialized before
the Node HTTP server and awaits until the promise is completed to kick
off the HTTP server.
### Alternative code
```js
let handler;
const server = http.createServer(async (req, res) => {
try {
await waitUntilHandlerIsReady(); // <---- wait here
await handler(req, res);
} catch (err) {
console.error("Failed to call handler", err);
res.statusCode = 500;
res.end("Internal Server Error");
}
});
async function waitUntilHandlerIsReady() {
if (!handler) {
await new Promise((resolve) => setTimeout(resolve, 200));
await waitUntilHandlerIsReady();
}
}
```
---------
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
Co-authored-by: JJ Kasper <jj@jjsweb.site>