From 5c4e2fabf5382134f07ce2f20252d9ea99acaab0 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 8 Nov 2021 17:42:50 +0100 Subject: [PATCH] error --- .../next-middleware-ssr-loader/index.ts | 3 ++- packages/next/server/render.tsx | 25 +++++++++++-------- .../app/pages/500.js | 3 +++ .../app/pages/err/render.js | 7 ++++++ .../app/pages/err/suspense.js | 20 +++++++++++++++ 5 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 test/integration/react-streaming-and-server-components/app/pages/500.js create mode 100644 test/integration/react-streaming-and-server-components/app/pages/err/render.js create mode 100644 test/integration/react-streaming-and-server-components/app/pages/err/suspense.js diff --git a/packages/next/build/webpack/loaders/next-middleware-ssr-loader/index.ts b/packages/next/build/webpack/loaders/next-middleware-ssr-loader/index.ts index b0ee97c93888..25f664f31b6f 100644 --- a/packages/next/build/webpack/loaders/next-middleware-ssr-loader/index.ts +++ b/packages/next/build/webpack/loaders/next-middleware-ssr-loader/index.ts @@ -162,7 +162,7 @@ export default async function middlewareRSCLoader(this: any) { const transformStream = new TransformStream() const writer = transformStream.writable.getWriter() const encoder = new TextEncoder() - + try { const result = await renderToHTML( { url: pathname }, @@ -175,6 +175,7 @@ export default async function middlewareRSCLoader(this: any) { write: str => writer.write(encoder.encode(str)), end: () => writer.close() }) + .catch(() => writer.close()) } catch (err) { return new Response( (err || 'An error occurred while rendering ' + pathname + '.').toString(), diff --git a/packages/next/server/render.tsx b/packages/next/server/render.tsx index fd44dbc070ce..0f8de8ca7da9 100644 --- a/packages/next/server/render.tsx +++ b/packages/next/server/render.tsx @@ -1450,19 +1450,24 @@ function renderToReadableStream( const reader = readable.getReader() const decoder = new TextDecoder() const process = () => { - reader.read().then(({ done, value }: any) => { - if (!done) { - const s = typeof value === 'string' ? value : decoder.decode(value) - if (shellCompleted) { - res.write(s) + reader.read().then( + ({ done, value }: any) => { + if (!done) { + const s = typeof value === 'string' ? value : decoder.decode(value) + if (shellCompleted) { + res.write(s) + } else { + bufferedString += s + } + process() } else { - bufferedString += s + next() } - process() - } else { - next() + }, + (err: any) => { + next(err) } - }) + ) } process() } diff --git a/test/integration/react-streaming-and-server-components/app/pages/500.js b/test/integration/react-streaming-and-server-components/app/pages/500.js new file mode 100644 index 000000000000..2e6a4c7bc953 --- /dev/null +++ b/test/integration/react-streaming-and-server-components/app/pages/500.js @@ -0,0 +1,3 @@ +export default function Page500() { + return 'custom-500-page' +} diff --git a/test/integration/react-streaming-and-server-components/app/pages/err/render.js b/test/integration/react-streaming-and-server-components/app/pages/err/render.js new file mode 100644 index 000000000000..c05e49826ae7 --- /dev/null +++ b/test/integration/react-streaming-and-server-components/app/pages/err/render.js @@ -0,0 +1,7 @@ +let did = false +export default function Error() { + if (!did && typeof window === 'undefined') { + did = true + throw new Error('oops') + } +} diff --git a/test/integration/react-streaming-and-server-components/app/pages/err/suspense.js b/test/integration/react-streaming-and-server-components/app/pages/err/suspense.js new file mode 100644 index 000000000000..645988d009dc --- /dev/null +++ b/test/integration/react-streaming-and-server-components/app/pages/err/suspense.js @@ -0,0 +1,20 @@ +import { Suspense } from 'react' + +let did = false +function Error() { + if (!did && typeof window === 'undefined') { + did = true + throw new Error('broken page') + } +} + +export default function page() { + return ( + <> +

Hey Error

+ + + + + ) +}