Skip to content

Commit 79bdd86

Browse files
committed
Fix presentation when onerror receives an event without error (#74643)
1 parent 1882acb commit 79bdd86

File tree

4 files changed

+73
-1
lines changed

4 files changed

+73
-1
lines changed

packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,11 @@ function onUnhandledError(event: WindowEventMap['error']): void | boolean {
7777
event.preventDefault()
7878
return false
7979
}
80-
handleClientError(event.error, [])
80+
// When there's an error property present, we log the error to error overlay.
81+
// Otherwise we don't do anything as it's not logging in the console either.
82+
if (event.error) {
83+
handleClientError(event.error, [])
84+
}
8185
}
8286

8387
function onUnhandledRejection(ev: WindowEventMap['unhandledrejection']): void {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use client'
2+
3+
export default function Page() {
4+
return (
5+
<button
6+
onClick={() => {
7+
// Create an ErrorEvent with only a message
8+
const errorEvent = new ErrorEvent('error', {
9+
message: 'dummy error message', // Message for the event
10+
// Omit the `error` property to ensure it is not included
11+
})
12+
13+
// Dispatch the event
14+
window.dispatchEvent(errorEvent)
15+
}}
16+
>
17+
click to trigger error event
18+
</button>
19+
)
20+
}

test/development/app-dir/capture-console-error/capture-console-error.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
getRedboxTotalErrorCount,
88
openRedbox,
99
hasRedboxCallStack,
10+
assertNoRedbox,
11+
assertNoConsoleErrors,
1012
} from 'next-test-utils'
1113

1214
async function getRedboxResult(browser: any) {
@@ -315,4 +317,12 @@ describe('app-dir - capture-console-error', () => {
315317
`)
316318
}
317319
})
320+
321+
it('should display the error message in error event when event.error is not present', async () => {
322+
const browser = await next.browser('/browser/error-event')
323+
await browser.elementByCss('button').click()
324+
325+
await assertNoRedbox(browser)
326+
await assertNoConsoleErrors(browser)
327+
})
318328
})

test/lib/next-test-utils.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,3 +1522,41 @@ export async function toggleCollapseCallStackFrames(browser: BrowserInterface) {
15221522
expect(currExpanded).not.toBe(lastExpanded)
15231523
})
15241524
}
1525+
1526+
/**
1527+
* Encodes the params into a URLSearchParams object using the format that the
1528+
* now builder uses for route matches (adding the `nxtP` prefix to the keys).
1529+
*
1530+
* @param params - The params to encode.
1531+
* @param extraQueryParams - The extra query params to encode (without the `nxtP` prefix).
1532+
* @returns The encoded URLSearchParams object.
1533+
*/
1534+
export function createNowRouteMatches(
1535+
params: Record<string, string>,
1536+
extraQueryParams: Record<string, string> = {}
1537+
): URLSearchParams {
1538+
const urlSearchParams = new URLSearchParams()
1539+
for (const [key, value] of Object.entries(params)) {
1540+
urlSearchParams.append(`nxtP${key}`, value)
1541+
}
1542+
for (const [key, value] of Object.entries(extraQueryParams)) {
1543+
urlSearchParams.append(key, value)
1544+
}
1545+
1546+
return urlSearchParams
1547+
}
1548+
1549+
export async function assertNoConsoleErrors(browser: BrowserInterface) {
1550+
const logs = await browser.log()
1551+
const warningsAndErrors = logs.filter((log) => {
1552+
return (
1553+
log.source === 'warning' ||
1554+
(log.source === 'error' &&
1555+
// These are expected when we visit 404 pages.
1556+
log.message !==
1557+
'Failed to load resource: the server responded with a status of 404 (Not Found)')
1558+
)
1559+
})
1560+
1561+
expect(warningsAndErrors).toEqual([])
1562+
}

0 commit comments

Comments
 (0)