diff --git a/packages/next/client/components/error-boundary.tsx b/packages/next/client/components/error-boundary.tsx index 2cb34ef2af63a23..56d9efd5bf451f9 100644 --- a/packages/next/client/components/error-boundary.tsx +++ b/packages/next/client/components/error-boundary.tsx @@ -70,7 +70,7 @@ export function ErrorBoundary({ return <>{children} } -const styles: { [k: string]: React.CSSProperties } = { +const styles = { error: { fontFamily: '-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif', @@ -81,7 +81,6 @@ const styles: { [k: string]: React.CSSProperties } = { alignItems: 'center', justifyContent: 'center', }, - desc: { display: 'inline-block', textAlign: 'left', @@ -89,25 +88,29 @@ const styles: { [k: string]: React.CSSProperties } = { height: '49px', verticalAlign: 'middle', }, - h2: { + text: { fontSize: '14px', fontWeight: 'normal', lineHeight: '49px', margin: 0, padding: 0, }, -} +} as const -export function GlobalErrorComponent() { +export function GlobalErrorComponent({ error }: { error: any }) { return ( +
-

+

Application error: a client-side exception has occurred (see the browser console for more information).

+ {error?.digest && ( +

{`Digest: ${error.digest}`}

+ )}
diff --git a/test/e2e/app-dir/app/app/error/global-error-boundary/page.js b/test/e2e/app-dir/app/app/error/global-error-boundary/client/page.js similarity index 100% rename from test/e2e/app-dir/app/app/error/global-error-boundary/page.js rename to test/e2e/app-dir/app/app/error/global-error-boundary/client/page.js diff --git a/test/e2e/app-dir/app/app/error/global-error-boundary/server/page.js b/test/e2e/app-dir/app/app/error/global-error-boundary/server/page.js new file mode 100644 index 000000000000000..eb01d208afc4b2c --- /dev/null +++ b/test/e2e/app-dir/app/app/error/global-error-boundary/server/page.js @@ -0,0 +1,3 @@ +export default function Page() { + throw Error('custom server error') +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 7c59d26cb6a622d..30ea13f6acc5693 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -2123,7 +2123,7 @@ describe('app dir', () => { it('should use default error boundary for prod and overlay for dev when no error component specified', async () => { const browser = await webdriver( next.url, - '/error/global-error-boundary' + '/error/global-error-boundary/client' ) await browser.elementByCss('#error-trigger-button').click() @@ -2132,16 +2132,34 @@ describe('app dir', () => { expect(await getRedboxHeader(browser)).toMatch(/this is a test/) } else { expect( - await browser - .waitForElementByCss('body') - .elementByCss('body') - .text() + await browser.waitForElementByCss('body').elementByCss('h2').text() ).toBe( 'Application error: a client-side exception has occurred (see the browser console for more information).' ) } }) + it('should display error digest for error in server component with default error boundary', async () => { + const browser = await webdriver( + next.url, + '/error/global-error-boundary/server' + ) + + if (isDev) { + expect(await hasRedbox(browser)).toBe(true) + expect(await getRedboxHeader(browser)).toMatch(/custom server error/) + } else { + expect( + await browser.waitForElementByCss('body').elementByCss('h2').text() + ).toBe( + 'Application error: a client-side exception has occurred (see the browser console for more information).' + ) + expect( + await browser.waitForElementByCss('body').elementByCss('p').text() + ).toMatch(/Digest: \w+/) + } + }) + if (!isDev) { it('should allow resetting error boundary', async () => { const browser = await webdriver(next.url, '/error/client-component')