From 79bdd868812e5eaa804a647cdfeb94a842d2070b Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 9 Jan 2025 20:23:33 +0100 Subject: [PATCH] Fix presentation when onerror receives an event without error (#74643) --- .../internal/helpers/use-error-handler.ts | 6 ++- .../app/browser/error-event/page.js | 20 ++++++++++ .../capture-console-error.test.ts | 10 +++++ test/lib/next-test-utils.ts | 38 +++++++++++++++++++ 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 test/development/app-dir/capture-console-error/app/browser/error-event/page.js diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts index 3fdfd27831179..a7ad315cc6bed 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts @@ -77,7 +77,11 @@ function onUnhandledError(event: WindowEventMap['error']): void | boolean { event.preventDefault() return false } - handleClientError(event.error, []) + // When there's an error property present, we log the error to error overlay. + // Otherwise we don't do anything as it's not logging in the console either. + if (event.error) { + handleClientError(event.error, []) + } } function onUnhandledRejection(ev: WindowEventMap['unhandledrejection']): void { diff --git a/test/development/app-dir/capture-console-error/app/browser/error-event/page.js b/test/development/app-dir/capture-console-error/app/browser/error-event/page.js new file mode 100644 index 0000000000000..345a48878a53c --- /dev/null +++ b/test/development/app-dir/capture-console-error/app/browser/error-event/page.js @@ -0,0 +1,20 @@ +'use client' + +export default function Page() { + return ( + + ) +} diff --git a/test/development/app-dir/capture-console-error/capture-console-error.test.ts b/test/development/app-dir/capture-console-error/capture-console-error.test.ts index 07c9b62e409b0..300a91ccc31b0 100644 --- a/test/development/app-dir/capture-console-error/capture-console-error.test.ts +++ b/test/development/app-dir/capture-console-error/capture-console-error.test.ts @@ -7,6 +7,8 @@ import { getRedboxTotalErrorCount, openRedbox, hasRedboxCallStack, + assertNoRedbox, + assertNoConsoleErrors, } from 'next-test-utils' async function getRedboxResult(browser: any) { @@ -315,4 +317,12 @@ describe('app-dir - capture-console-error', () => { `) } }) + + it('should display the error message in error event when event.error is not present', async () => { + const browser = await next.browser('/browser/error-event') + await browser.elementByCss('button').click() + + await assertNoRedbox(browser) + await assertNoConsoleErrors(browser) + }) }) diff --git a/test/lib/next-test-utils.ts b/test/lib/next-test-utils.ts index b8b7ed2310a42..692582a369f08 100644 --- a/test/lib/next-test-utils.ts +++ b/test/lib/next-test-utils.ts @@ -1522,3 +1522,41 @@ export async function toggleCollapseCallStackFrames(browser: BrowserInterface) { expect(currExpanded).not.toBe(lastExpanded) }) } + +/** + * Encodes the params into a URLSearchParams object using the format that the + * now builder uses for route matches (adding the `nxtP` prefix to the keys). + * + * @param params - The params to encode. + * @param extraQueryParams - The extra query params to encode (without the `nxtP` prefix). + * @returns The encoded URLSearchParams object. + */ +export function createNowRouteMatches( + params: Record, + extraQueryParams: Record = {} +): URLSearchParams { + const urlSearchParams = new URLSearchParams() + for (const [key, value] of Object.entries(params)) { + urlSearchParams.append(`nxtP${key}`, value) + } + for (const [key, value] of Object.entries(extraQueryParams)) { + urlSearchParams.append(key, value) + } + + return urlSearchParams +} + +export async function assertNoConsoleErrors(browser: BrowserInterface) { + const logs = await browser.log() + const warningsAndErrors = logs.filter((log) => { + return ( + log.source === 'warning' || + (log.source === 'error' && + // These are expected when we visit 404 pages. + log.message !== + 'Failed to load resource: the server responded with a status of 404 (Not Found)') + ) + }) + + expect(warningsAndErrors).toEqual([]) +}