Skip to content

Commit

Permalink
test: the nextjs internal errors should not be caught (#67671)
Browse files Browse the repository at this point in the history
### What

Cover the Next.js internal errors are not captured by instrumentation
onRequestError API

Also skip deployment tests for onRequestError API due to the private env
flag `__NEXT_EXPERIMENTAL_INSTRUMENTATION` cannot be used in deployment

<!-- Closes NDX-33 -->
  • Loading branch information
huozhi committed Jul 12, 2024
1 parent a329371 commit 38a6b01
Show file tree
Hide file tree
Showing 16 changed files with 176 additions and 1 deletion.
7 changes: 6 additions & 1 deletion test/e2e/on-request-error/basic/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ import { nextTestSetup } from 'e2e-utils'
import { retry } from 'next-test-utils'

describe('on-request-error - basic', () => {
const { next } = nextTestSetup({
const { next, skipped } = nextTestSetup({
files: __dirname,
skipDeployment: true,
env: {
__NEXT_EXPERIMENTAL_INSTRUMENTATION: '1',
},
})

if (skipped) {
return
}

const outputLogPath = 'output-log.json'

async function getOutputLogJson() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Page() {
return <p>another</p>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { notFound } from 'next/navigation'

export function GET() {
notFound()
}

export const dynamic = 'force-dynamic'
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { redirect } from 'next/navigation'

export function GET() {
redirect('/another')
}

export const dynamic = 'force-dynamic'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default async function Page() {
await fetch('https://example.vercel.sh')
return <p>dynamic page</p>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Component() {
return <p>Component</p>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use client'

import nextDynamic from 'next/dynamic'

const Component = nextDynamic(() => import('./component'))

export default function Page() {
return <Component />
}

export const dynamic = 'force-dynamic'
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use client'

import { notFound } from 'next/navigation'

export default function Page() {
notFound()
}

export const dynamic = 'force-dynamic'
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use client'

import { redirect } from 'next/navigation'

export default function Page() {
redirect('/another')
}

export const dynamic = 'force-dynamic'
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function Layout({ children }) {
return (
<html>
<body>{children}</body>
</html>
)
}

export const dynamic = 'force-dynamic'
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default async function Page() {
await fetch('https://example.vercel.sh')
return <p>dynamic page</p>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { notFound } from 'next/navigation'

export default function Page() {
notFound()
}

export const dynamic = 'force-dynamic'
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { redirect } from 'next/navigation'

export default function Page() {
redirect('/another')
}

export const dynamic = 'force-dynamic'
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function onRequestError(err, request, context) {
console.log('[instrumentation]:error', err.message)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
experimental: {
instrumentationHook: true,
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { nextTestSetup } from 'e2e-utils'

describe('on-request-error - skip-next-internal-error', () => {
const { next, skipped } = nextTestSetup({
files: __dirname,
skipDeployment: true,
env: {
__NEXT_EXPERIMENTAL_INSTRUMENTATION: '1',
},
})

if (skipped) {
return
}

async function assertNoNextjsInternalErrors() {
const output = next.cliOutput
// No navigation errors
expect(output).not.toContain('NEXT_REDIRECT')
expect(output).not.toContain('NEXT_NOT_FOUND')
expect(output).not.toContain('BAILOUT_TO_CLIENT_SIDE_RENDERING')
// No dynamic usage errors
expect(output).not.toContain('DYNAMIC_SERVER_USAGE')
// No react postpone errors
// TODO: cover PPR errors later
expect(output).not.toContain('react.postpone')
}

describe('app router render', () => {
// Server navigation errors
it('should not catch server component not-found errors', async () => {
await next.fetch('/server/not-found')
await assertNoNextjsInternalErrors()
})

it('should not catch server component redirect errors', async () => {
await next.render('/server/redirect')
await assertNoNextjsInternalErrors()
})

// Client navigation errors
it('should not catch client component not-found errors', async () => {
await next.fetch('/server/not-found')
await assertNoNextjsInternalErrors()
})

it('should not catch client component redirect errors', async () => {
await next.render('/client/redirect')
await assertNoNextjsInternalErrors()
})

// Dynamic usage
it('should not catch server component dynamic usage errors', async () => {
await next.fetch('/server/dynamic-fetch')
await assertNoNextjsInternalErrors()
})

it('should not catch client component dynamic usage errors', async () => {
await next.fetch('/client/dynamic-fetch')
await assertNoNextjsInternalErrors()
})

// No SSR
it('should not catch next dynamic no-ssr errors', async () => {
await next.fetch('/client/no-ssr')
await assertNoNextjsInternalErrors()
})
})

describe('app router API', () => {
// API routes navigation errors
it('should not catch server component not-found errors', async () => {
await next.render('/app-route/not-found')
await assertNoNextjsInternalErrors()
})

it('should not catch server component redirect errors', async () => {
await next.render('/app-route/redirect')
await assertNoNextjsInternalErrors()
})
})
})

0 comments on commit 38a6b01

Please sign in to comment.