Skip to content
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

Merged
merged 1 commit into from
Apr 5, 2025

Conversation

alan-agius4
Copy link
Collaborator

@alan-agius4 alan-agius4 commented Sep 12, 2024

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

@angular-robot angular-robot bot added detected: feature PR contains a feature commit area: @angular/ssr labels Sep 12, 2024
@alan-agius4 alan-agius4 added action: review The PR is still awaiting reviews from at least one requested reviewer target: major This PR is targeted for the next major release labels Sep 12, 2024
@alan-agius4 alan-agius4 changed the title feat(@angular/ssr): feat: add attachNodeErrorHandlers to manage unhandled errors feat(@angular/ssr): add attachNodeErrorHandlers to manage unhandled errors Sep 12, 2024
@alan-agius4 alan-agius4 changed the title feat(@angular/ssr): add attachNodeErrorHandlers to manage unhandled errors feat(@angular/ssr): add attachNodeErrorHandlers to manage unhandled errors Sep 12, 2024
@alan-agius4 alan-agius4 force-pushed the handler-errors-node.js branch from 79df9ba to f922b3d Compare September 12, 2024 12:53
@alan-agius4 alan-agius4 added action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Sep 12, 2024
@alan-agius4 alan-agius4 removed the request for review from atscott October 7, 2024 07:26
@alan-agius4 alan-agius4 force-pushed the handler-errors-node.js branch from f922b3d to 95afc9c Compare October 7, 2024 07:27
@alan-agius4 alan-agius4 changed the title feat(@angular/ssr): add attachNodeErrorHandlers to manage unhandled errors feat(@angular/ssr): add attachNodeGlobalErrorHandlers to manage unhandled errors Oct 7, 2024
@alan-agius4 alan-agius4 force-pushed the handler-errors-node.js branch 2 times, most recently from 623f923 to c49f72b Compare October 7, 2024 07:59
@alan-agius4 alan-agius4 removed the action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews label Oct 7, 2024
@alan-agius4 alan-agius4 changed the title feat(@angular/ssr): add attachNodeGlobalErrorHandlers to manage unhandled errors fix(@angular/ssr): manage unhandled errors in zoneless applications Oct 7, 2024
@alan-agius4 alan-agius4 added the action: review The PR is still awaiting reviews from at least one requested reviewer label Oct 7, 2024
@alan-agius4 alan-agius4 force-pushed the handler-errors-node.js branch from c49f72b to 905df8f Compare October 7, 2024 09:32
@angular-robot angular-robot bot removed the detected: feature PR contains a feature commit label Oct 7, 2024
@alan-agius4 alan-agius4 force-pushed the handler-errors-node.js branch 3 times, most recently from 53536c8 to 81f7fc6 Compare October 7, 2024 09:57
// 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));
Copy link
Contributor

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"?

Copy link
Contributor

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.

Copy link
Collaborator Author

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.

Copy link
Member

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.

Copy link
Contributor

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.

Copy link
Member

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

Copy link
Contributor

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..?

Copy link
Collaborator Author

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.

@alan-agius4 alan-agius4 closed this Oct 8, 2024
@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Nov 9, 2024
@alan-agius4 alan-agius4 reopened this Apr 1, 2025
@alan-agius4 alan-agius4 force-pushed the handler-errors-node.js branch from 81f7fc6 to 44d8d17 Compare April 1, 2025 08:32
@alan-agius4 alan-agius4 requested review from jkrems, atscott and alxhub and removed request for pkozlowski-opensource and alxhub April 1, 2025 08:32
@alan-agius4 alan-agius4 force-pushed the handler-errors-node.js branch from 44d8d17 to 62bf1a8 Compare April 1, 2025 08:34
@angular angular deleted a comment from angular-automatic-lock-bot bot Apr 1, 2025
@alan-agius4 alan-agius4 force-pushed the handler-errors-node.js branch from 62bf1a8 to e92c432 Compare April 1, 2025 09:52
@@ -22,6 +23,10 @@ import { createWebRequestFromNodeRequest } from './request';
export class AngularNodeAppEngine {
private readonly angularAppEngine = new AngularAppEngine();

constructor() {
attachNodeGlobalErrorHandlers();
Copy link
Collaborator Author

@alan-agius4 alan-agius4 Apr 1, 2025

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

@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker action: review The PR is still awaiting reviews from at least one requested reviewer and removed action: review The PR is still awaiting reviews from at least one requested reviewer action: merge The PR is ready for merge by the caretaker labels Apr 2, 2025
@alan-agius4 alan-agius4 force-pushed the handler-errors-node.js branch from e92c432 to 72d3485 Compare April 3, 2025 08:11
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
@alan-agius4 alan-agius4 force-pushed the handler-errors-node.js branch from 72d3485 to b9efb62 Compare April 4, 2025 06:20
@alan-agius4 alan-agius4 removed the request for review from alxhub April 5, 2025 12:29
@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Apr 5, 2025
@alan-agius4 alan-agius4 merged commit 319b8e0 into angular:main Apr 5, 2025
30 checks passed
@alan-agius4 alan-agius4 deleted the handler-errors-node.js branch April 5, 2025 12:30
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: @angular/ssr target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Vite dev server crashes when HttpClient receives non-200 code
5 participants