fix(@angular/build): preserve error stack traces during prerendering#32864
fix(@angular/build): preserve error stack traces during prerendering#32864maruthang wants to merge 1 commit intoangular:mainfrom
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request reorders error property access to prioritize stack traces over messages when reporting failures during the prerendering process. The reviewer suggested enhancing type safety and consistency across the file by utilizing assertIsError within the catch blocks and ensuring the error code is included in all error messages.
| return { | ||
| errors: [`An error occurred while extracting routes.\n\n${err.message ?? err.stack ?? err}`], | ||
| errors: [`An error occurred while extracting routes.\n\n${err.stack ?? err.message ?? err}`], | ||
| serializedRouteTree: [], | ||
| appShellRoute: undefined, | ||
| }; |
There was a problem hiding this comment.
For consistency with other error handling in this file (see line 370) and to improve type safety, it is a good practice to assert the error type using assertIsError. This also allows you to safely include err.code in the error message, which can be valuable for debugging, especially for potential filesystem errors from readFile in getAllRoutes.
assertIsError(err);
return {
errors: ["An error occurred while extracting routes.\n\n" + (err.stack ?? err.message ?? err.code ?? err)],
serializedRouteTree: [],
appShellRoute: undefined,
};| errors.push( | ||
| `An error occurred while prerendering route '${route}'.\n\n${err.message ?? err.stack ?? err.code ?? err}`, | ||
| `An error occurred while prerendering route '${route}'.\n\n${err.stack ?? err.message ?? err.code ?? err}`, | ||
| ); | ||
| void renderWorker.destroy(); |
There was a problem hiding this comment.
To ensure type safety and for consistency with other error handling in this file (e.g., line 370), consider adding assertIsError(err) at the beginning of this catch block. This will guarantee that err is an Error object before its properties are accessed.
assertIsError(err);
errors.push(
"An error occurred while prerendering route '" + route + "'.\n\n" + (err.stack ?? err.message ?? err.code ?? err),
);
void renderWorker.destroy();Reorder the nullish coalescing chain from `err.message ?? err.stack` to `err.stack ?? err.message` so that the full stack trace is preserved when available. Since `err.message` is almost always defined on Error objects, the previous order meant `err.stack` was never reached. Also add `assertIsError(err)` and consistent `err.code` inclusion across all three error-handling locations for improved type safety and debugging. Fixes angular#32503
cf5c56d to
f4e029d
Compare
PR Checklist
PR Type
What is the current behavior?
When prerendering fails, the error output shows only the error message but no stack trace, making debugging very difficult. This is because the nullish coalescing chain
err.message ?? err.stack ?? erralways resolves toerr.message(since it's almost always defined on Error objects), soerr.stackis never reached.Issue Number: #32503
What is the new behavior?
Reorder the chain to
err.stack ?? err.message ?? errat all three error-handling locations inprerender.ts. Sinceerr.stackincludes the message as its first line plus the full trace, this preserves all debugging information.Does this PR introduce a breaking change?