Files
Janka Uryga 42090c596e fix: prevent router errors from being logged on the client (#71583)
Our patched `console.error` tries to skip internal router errors by
checking `isNextRouterError(error)`. however, if one of those happened
on the server and got replayed on the client, it gets logged differently
-- it's prefixed with the `[ Server ]` badge. this changes the position
where the actual error object is in `args` and thus messes up our
detection, so we end up printing it out (instead of hiding it like we
should)

This PR adds a check that attempts to match replayed server errors
(following [similar logic from react
devtools](https://github.com/facebook/react/blob/65a56d0e99261481c721334a3ec4561d173594cd/packages/react-devtools-shared/src/backend/flight/renderer.js#L88-L93))
and thus also filter out router errors that originated on the server


Closes #71555
2024-10-22 13:34:37 +00:00

78 lines
2.4 KiB
TypeScript

/* eslint-env jest */
import { nextTestSetup } from 'e2e-utils'
import { retry } from '../../lib/next-test-utils'
describe('Replaying internal errors', () => {
const { next } = nextTestSetup({ files: __dirname })
it('should not log the internal error thrown by redirect()', async () => {
const EXPECTED_REPLAYED_MESSAGE = 'This error should get replayed'
const OMITTED_ERROR_MESSAGE = 'NEXT_REDIRECT'
const browser = await next.browser('/')
await browser.elementByCss('a[href="/will-redirect"]').click()
await retry(async () => {
expect(await browser.elementByCss('h1').text()).toBe('Redirected')
})
expect(next.cliOutput).toContain(EXPECTED_REPLAYED_MESSAGE)
expect(next.cliOutput).not.toContain(OMITTED_ERROR_MESSAGE)
// It'd be good to check for redbox here,
// but it seems to disappear the first time we navigate to /target.
// But checking console errors should be enough because they're closely tied
const logs = await browser.log()
expect(logs).toContainEqual(
expect.objectContaining({
source: 'error',
message: expect.stringContaining(EXPECTED_REPLAYED_MESSAGE),
})
)
expect(logs).not.toContainEqual(
expect.objectContaining({
source: 'error',
message: expect.stringContaining(OMITTED_ERROR_MESSAGE),
})
)
})
it('should not log the internal error thrown by notFound()', async () => {
const EXPECTED_REPLAYED_MESSAGE = 'This error should get replayed'
const OMITTED_ERROR_MESSAGE = 'NEXT_NOT_FOUND'
const browser = await next.browser('/')
await browser.elementByCss('a[href="/will-notfound"]').click()
await retry(async () => {
expect(await browser.elementByCss('h1').text()).toBe('Not found')
})
expect(next.cliOutput).toContain(EXPECTED_REPLAYED_MESSAGE)
expect(next.cliOutput).not.toContain(OMITTED_ERROR_MESSAGE)
// It'd be good to check for redbox here,
// but it seems to disappear the first time we navigate to /target.
// But checking console errors should be enough because they're closely tied
const logs = await browser.log()
expect(logs).toContainEqual(
expect.objectContaining({
source: 'error',
message: expect.stringContaining(EXPECTED_REPLAYED_MESSAGE),
})
)
expect(logs).not.toContainEqual(
expect.objectContaining({
source: 'error',
message: expect.stringContaining(OMITTED_ERROR_MESSAGE),
})
)
})
})