-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(@angular/ssr): manage unhandled errors in zoneless applications #28405
Conversation
attachNodeErrorHandlers
to manage unhandled errors
79df9ba
to
f922b3d
Compare
f922b3d
to
95afc9c
Compare
attachNodeErrorHandlers
to manage unhandled errorsattachNodeGlobalErrorHandlers
to manage unhandled errors
623f923
to
c49f72b
Compare
attachNodeGlobalErrorHandlers
to manage unhandled errorsc49f72b
to
905df8f
Compare
53536c8
to
81f7fc6
Compare
// eslint-disable-next-line no-console | ||
.on('unhandledRejection', (error) => console.error('unhandledRejection', error)) | ||
// eslint-disable-next-line no-console | ||
.on('uncaughtException', (error) => console.error('uncaughtException', error)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's worth noting that this leaves the process in an undefined state which may cause resource leaks and other unexpected behavior. See also: https://nodejs.org/api/process.html#warning-using-uncaughtexception-correctly
Could this behavior be made optional and come with "buyer beware"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 - discussions with @alxhub and @pkozlowski-opensource before going on leave were around not doing this and needing the framework to handle application errors instead.
This handler makes a choice about errors coming from more than just the framework/application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally agree, I wasn’t aware that things change since we last talked.
I definitely agree that the FW should handle errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree as well - in general I would favor letting a process crash and restart if an error escapes the individual request scope. At that point, you can't really guarantee it can safely continue processing requests.
I wonder if there's potential for some kind of graceful shutdown though, where an uncaught error doesn't terminate the process immediately, but stops accepting new requests and gives some timeout for existing ones to shut down.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to chat more about options here. Unfortunately, there is (or at least used to be) no easy way to stop accepting new requests (vs. accepting new connections). IIRC the best strategy was to check on the end of requests if there's other concurrent requests on the same connection and using that to separate connections to proxies/load balancers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should Angular servers implement /healthz
? :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a really interesting open question because it says a lot about what this server is. Actually curious about what (if anything) other backend-for-frontend-in-a-box solutions do for this. Wouldn't be surprised if the answer is "not much" since it doesn't matter for most apps if a couple of concurrent requests end up with preventable 500s when something goes wrong..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following the discussions we had recently. I re-opened the PR.
81f7fc6
to
44d8d17
Compare
44d8d17
to
62bf1a8
Compare
62bf1a8
to
e92c432
Compare
@@ -22,6 +23,10 @@ import { createWebRequestFromNodeRequest } from './request'; | |||
export class AngularNodeAppEngine { | |||
private readonly angularAppEngine = new AngularAppEngine(); | |||
|
|||
constructor() { | |||
attachNodeGlobalErrorHandlers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an alternative, we can export this a public API, and let the users invoke it manually in the server.ts
e92c432
to
72d3485
Compare
Implement the `attachNodeGlobalErrorHandlers` function to handle 'unhandledRejection' and 'uncaughtException' events in Node.js. This function logs errors to the console, preventing unhandled errors from crashing the server. It is particularly useful for zoneless apps, ensuring error handling without relying on zones. Closes angular/angular#58123
72d3485
to
b9efb62
Compare
Implement the
attachNodeGlobalErrorHandlers
function to handle 'unhandledRejection' and 'uncaughtException' events in Node.js. This function logs errors to the console, preventing unhandled errors from crashing the server. It is particularly useful for zoneless apps, ensuring error handling without relying on zones.Closes angular/angular#58123