Next.js production build doesn't prevent process exiting due to unhandled exceptions
See original GitHub issueBug report
Describe the bug
Next.js process exits with code 1 when API route throws exception in production mode.
A common mistake that could easily lay dormant causes Next.js to exit the PRODUCTION server when it eventually gets run. Yes, I understand pragmatically you shouldn’t be masking response errors, but I don’t feel very confident using Next.js in production, when a simple race condition that’s almost never triggered can bring down the server.
To Reproduce
$ npx create-next-app production-process-exits
// pages/api/hello.js
export default (req, res) => {
res.end().write()
}
Or
// pages/api/hello.js
export default (req, res) => {
setTimeout(() => res.write(), 1000)
res.end()
}
$ yarn build
$ yarn start
Visit http://localhost:3000/api/hello, see process exit with the following stack trace:
events.js:287
throw er; // Unhandled 'error' event
^
Error [ERR_STREAM_WRITE_AFTER_END]: write after end
at write_ (_http_outgoing.js:637:17)
at ServerResponse.write (_http_outgoing.js:629:15)
at ServerResponse.write (/home/max/production-process-exits/node_modules/next/dist/compiled/compression/index.js:1:148632)
at Timeout.eval [as _onTimeout] (webpack-internal:///./pages/api/hello.js:4:24)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7)
Emitted 'error' event on ServerResponse instance at:
at writeAfterEndNT (_http_outgoing.js:692:7)
at processTicksAndRejections (internal/process/task_queues.js:85:21) {
code: 'ERR_STREAM_WRITE_AFTER_END'
}
error Command failed with exit code 1.
Expected behavior
Error should be output without exiting the process.
System information
- OS: Ubuntu 20.04
- Version of Next.js: 9.5.3
- Version of Node.js: 12.16.3
Additional Context
Short of wrapping my entire API in a try/catch block, I am using the following workaround at the entrypoint of my app:
// pages/_app.js
if (process.env.NODE_ENV === 'production') {
process.on('uncaughtException', (error) => {
console.error(error.stack)
// Don't run process.exit(1)
})
}
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp
Issue Analytics
- State:
- Created 3 years ago
- Reactions:7
- Comments:5 (3 by maintainers)
Top Results From Across the Web
Inconsistent Exception/Error Handling (500 Internal Server ...
api routes will crash next, see Next.js production build doesn't prevent process exiting due to unhandled exceptions #17574 ...
Read more >Advanced Features: Error Handling - Next.js
Error Handling. This documentation explains how you can handle development, server-side, and client-side errors. Handling Errors in Development.
Read more >How do I prevent node from logging an exception to the ...
I catch this exception in my NextJS _error.js file, which is similar to a React error boundary, where I route the user to...
Read more >How to Throw Exceptions in Node.js - Rollbar
Node.js Throw Exception; How do you protect your application against ... they often lead to catastrophic issues that can crash your program.
Read more >Best Practices for Node.js Error-handling - Toptal
isTrustedError(error)) { process.exit(1); } });. Last but not least, I am going to mention dealing with unhandled promise rejections and exceptions.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Let it crash!
From my point of view this is the wanted behaviour.
Keeping the node process running on uncaught exceptions may lead to new errors (e.g. Memory Leaks, CPU peaks, etc.) that may be very hard to debug.
Your production setup should handle these crashes. Check out the following links if you want to know how:
This has been fixed a while ago, we now
process.exit(0)
at the end of the build process when there are no errors.