-
Notifications
You must be signed in to change notification settings - Fork 371
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
feat: CXSPA-6578 Introduce PROPAGATE_SERVER_ERROR_RESPONSE and default ExpressJS handlers #18753
Conversation
…t ExpressJS handlers
projects/storefrontapp/server.ts
Outdated
server.use(handleCmsPageNotFoundErrorResponse(indexHtmlContent)); | ||
server.use(handleUnknownServerErrorResponse(indexHtmlContent)); | ||
|
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.
Strategic question: how do we plan to distribute our error handlers to customers?
- will we be adding them to their server.ts with schematics?
- if yes, do we plan to put them one by one or somehow wrap them in one uber-error-handler, a.k.a. server.use(defaultServerErrorResponseHandlers()) // import defaultServerErrorResponseHandlers from @spartacus/setup/ssr?
- thanks to this, over time we will be able to introduce changes/additions if needed - in existing apps. For example, we can easily add a temporaryRedirectErrorHandler (sending 302) if we really want to
- if yes, do we plan to put them one by one or somehow wrap them in one uber-error-handler, a.k.a. server.use(defaultServerErrorResponseHandlers()) // import defaultServerErrorResponseHandlers from @spartacus/setup/ssr?
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.
Yes, the idea is to provide it to fresh SPA apps via schematics. uber-error-handler
is a tempting idea giving us possibilities for easier adjustments. The reason why I decided to introduce separate handlers was the question what if the customer wants to have our handler for unknown server errors, but they custom handler with an error page for 404?
Actually, now I have an answer... the custom handler can be provided before ours. What do you think about that?
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.
IMHO the most frequent use cases should be handled with a simple config, or super simple API. Ideally enabled implicitly by default. Medium-frequent use cases should require a tiny bit of coding, but proportionally to how often it is a use case. And for edge cases it's acceptable that customers might need to give up many OOTB default APIs and possibly write a lot of copy-pasted code + some customizations. (https://blog.platis.dev/open-source)
And in this case, in my opinion, default error handlers are good enough for most people. So, it should be a super simple and ergonomic API to use. Ideally implicit, but unfortunately, it's not possible because you have to put it explictly into the server.ts file.
If someone wants to add their error handlers - well, you nicely noticed that they can add their own above ours!! Nice catch!
If someone would like to remove one of our handlers at all, then they might want to remove our pack of error handlers. But for ergonomics, let's expose in our public APi all individuall handlers - so customers can pick and mix whatever they want, explicitly.
core-libs/setup/ssr/error-handling/server-error-response/propagate-server-error-response.ts
Outdated
Show resolved
Hide resolved
core-libs/setup/ssr/error-handling/multi-error-handlers/server-responding-error-handler.ts
Outdated
Show resolved
Hide resolved
core-libs/setup/ssr/error-handling/multi-error-handlers/server-responding-error-handler.ts
Outdated
Show resolved
Hide resolved
@@ -38,23 +38,34 @@ describe('CmsPageNotFoundServerErrorResponse', () => { | |||
expect(cmsPageNotFoundServerErrorResponse.getPriority()).toBe(Priority.LOW); | |||
}); | |||
|
|||
it('should match if error is an instance of HttpErrorResponse and URL starts with proper OCC endpoint including /cms/pages', () => { | |||
it('should match if error is an instance of HttpErrorResponse and, status is 404 and URL starts with proper OCC endpoint including /cms/pages', () => { |
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('should match if error is an instance of HttpErrorResponse and, status is 404 and URL starts with proper OCC endpoint including /cms/pages', () => { | |
it('should match if: error is an instance of HttpErrorResponse and status is 404 and URL starts with proper OCC endpoint including /cms/pages', () => { |
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.
Not sure whether I like the proposal more 🤔
...bs/setup/ssr/error-handling/server-error-response-handlers/server-error-response-handlers.ts
Outdated
Show resolved
Hide resolved
core-libs/setup/ssr/error-handling/server-error-response/propagate-server-error-response.ts
Outdated
Show resolved
Hide resolved
...bs/setup/ssr/error-handling/server-error-response-handlers/server-error-response-handlers.ts
Outdated
Show resolved
Hide resolved
core-libs/setup/ssr/error-handling/server-error-response/propagate-server-error-response.ts
Outdated
Show resolved
Hide resolved
Co-authored-by: Krzysztof Platis <platonn.git@gmail.com>
…gate-server-error-response.ts Co-authored-by: Krzysztof Platis <platonn.git@gmail.com>
Co-authored-by: Krzysztof Platis <platonn.git@gmail.com>
This PR introduces the
PROPAGATE_SERVER_ERROR_RESPONSE
injection token which helps to propagate errors that occur during server-side rendering. This covers Angular's loophole in dealing with errors that occur during SSR - by default, Angular returns HTML with a status of 200, regardless of the errors that occur, which can malformed the output.Thanks to this propagator, we can catch errors in the wrapper for CommonEngine responsible for rendering and return them instead of the malformed rendered view.
Together with this PR, we provide
defaultServerErrorResponseHandlers
function for ExpressJS, which helps to deal with caught errors:Customer can also provide their handlers and use them inside the
server.js
file instead of the ones we provided.QA steps:
pages
property indefault-cms-config.ts
to generateCmsPageNotFoundServerError
components
property indefault-cms-config.ts
to generateUnknownServerError
run dev:ssr
index.html
returned with status404
ifpages
endpoint has been modified indefault-cms-config.ts
index.html
returned with status500
ifcomponents
endpoint has been modified indefault-cms-config.ts
npx ts-node ./tools/schematics/testing.ts in the SPA root folder
npx @angular/cli new my-app --standalone=false --ssr=false --style=scss --routing=false
npx @angular/cli add @spartacus/schematics@latest --ssr
server.ts
insideapp
function use handlers provided by Spartacus:npm run build
andnpm run serve:ssr:my-app
to verify if server error responses have been handled as in test case 1npm i -d @types/ejs ejs
404.ejs
:server.ts
, use handler insideapp
function:npm run build
andnpm run serve:ssr:my-app
to verify if the custom handler workscloses CXSPA-6578