From 1b7d5973521d9cdd74db482ed2099e57170150cc Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 20 Mar 2024 16:16:04 +0800 Subject: [PATCH] fix: ctx.error with fatal options should work with the async loader function (#580) Co-authored-by: Michael --- CONTRIBUTING.md | 10 ++++++++++ .../shuvi-app/react/view/ReactView.server.tsx | 20 +++++++++++-------- .../loader/src/routes/fatal-error/page.tsx | 9 +++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5cfdf5d31..8570a6cdd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,6 +49,16 @@ configuring for webpack, babel, etc. Type definitions for shuvi. +## Prerequisites + +### Install cargo + +```bash +$ curl https://sh.rustup.rs -sSf | sh +``` + +> docs: https://doc.rust-lang.org/cargo/getting-started/installation.html + ## Setting Up a Local Copy 1. Clone the repo with `git clone https://github.com/liximomo/shuvi` diff --git a/packages/platform-web/src/shuvi-app/react/view/ReactView.server.tsx b/packages/platform-web/src/shuvi-app/react/view/ReactView.server.tsx index ac1e60fbf..bc40ccf82 100644 --- a/packages/platform-web/src/shuvi-app/react/view/ReactView.server.tsx +++ b/packages/platform-web/src/shuvi-app/react/view/ReactView.server.tsx @@ -19,12 +19,7 @@ export class ReactServerView implements IReactServerView { renderApp: IReactServerView['renderApp'] = async ({ req, app, manifest }) => { await Loadable.preloadAll(); - const { - router, - appComponent: AppComponent, - setError: setAppError, - error - } = app; + const { router, appComponent: AppComponent, setError: setAppError } = app; await router.ready; // todo: move these into renderer @@ -34,8 +29,17 @@ export class ReactServerView implements IReactServerView { setAppError(SHUVI_ERROR.PAGE_NOT_FOUND); } - if (error && error.fatal) { - return response('', { status: error.code, statusText: error.message }); + /** + * @Note Please note that you should not use `error` directly, please + * use `app.error` instead. + * ❌ if (error && error.fatal) + * ✅ if (app.error && app.error.fatal) + */ + if (app.error && app.error.fatal) { + return response('', { + status: app.error.code, + statusText: app.error.message + }); } if (redirected) { diff --git a/test/fixtures/loader/src/routes/fatal-error/page.tsx b/test/fixtures/loader/src/routes/fatal-error/page.tsx index 7b6ce59e2..f282b7326 100644 --- a/test/fixtures/loader/src/routes/fatal-error/page.tsx +++ b/test/fixtures/loader/src/routes/fatal-error/page.tsx @@ -1,7 +1,16 @@ import React from 'react'; import { Loader } from '@shuvi/runtime'; +async function sleep(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + export const loader: Loader = async ctx => { + /** + * Add a delay to verify the fatal error handling should work as + * expected. + */ + await sleep(100); ctx.error('Not Found', 404, { fatal: true }); return null; };