Skip to content

Commit

Permalink
DX: add route context to dynamic errors for app routes (#62844)
Browse files Browse the repository at this point in the history
Gives the users pathname context on routes that access Dynamic API's so
that if these errors are caught they can modify their code accordingly.
This is a followup to #61332.


Closes NEXT-2695
  • Loading branch information
wyattjoh committed Mar 8, 2024
1 parent 31a3aff commit ea56c8f
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ const staticGenerationRequestHandlers = {
case 'arrayBuffer':
case 'formData':
throw new DynamicServerError(
`Route couldn't be rendered statically because it accessed \`request.${prop}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`
`Route ${target.nextUrl.pathname} couldn't be rendered statically because it accessed \`request.${prop}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`
)
case 'clone':
return (
Expand Down Expand Up @@ -733,7 +733,7 @@ const staticGenerationNextUrlHandlers = {
case 'toString':
case 'origin':
throw new DynamicServerError(
`Route couldn't be rendered statically because it accessed \`nextUrl.${prop}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`
`Route ${target.pathname} couldn't be rendered statically because it accessed \`nextUrl.${prop}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`
)
case 'clone':
return (
Expand Down Expand Up @@ -776,7 +776,7 @@ const requireStaticRequestHandlers = {
case 'arrayBuffer':
case 'formData':
throw new StaticGenBailoutError(
`Route with \`dynamic = "error"\` couldn't be rendered statically because it accessed \`request.${prop}\`.`
`Route ${target.nextUrl.pathname} with \`dynamic = "error"\` couldn't be rendered statically because it accessed \`request.${prop}\`.`
)
case 'clone':
return (
Expand Down Expand Up @@ -821,7 +821,7 @@ const requireStaticNextUrlHandlers = {
case 'toString':
case 'origin':
throw new StaticGenBailoutError(
`Route with \`dynamic = "error"\` couldn't be rendered statically because it accessed \`nextUrl.${prop}\`.`
`Route ${target.pathname} with \`dynamic = "error"\` couldn't be rendered statically because it accessed \`nextUrl.${prop}\`.`
)
case 'clone':
return (
Expand Down
17 changes: 17 additions & 0 deletions test/e2e/app-dir/dynamic-data/dynamic-data.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,17 @@ createNextDescribe(

expect($('#searchparams .foo').text()).toBe('foosearch')
})

if (!isNextDev) {
it('should track dynamic apis when rendering app routes', async () => {
expect(next.cliOutput).toContain(
`Caught Error: Dynamic server usage: Route /routes/url couldn't be rendered statically because it accessed \`request.url\`.`
)
expect(next.cliOutput).toContain(
`Caught Error: Dynamic server usage: Route /routes/next-url couldn't be rendered statically because it accessed \`nextUrl.toString\`.`
)
})
}
}
)

Expand Down Expand Up @@ -227,6 +238,12 @@ createNextDescribe(
expect(next.cliOutput).toMatch(
'Error: Route /search with `dynamic = "error"` couldn\'t be rendered statically because it used `searchParams`.'
)
expect(next.cliOutput).toMatch(
'Error: Route /routes/form-data/error with `dynamic = "error"` couldn\'t be rendered statically because it accessed `request.formData`.'
)
expect(next.cliOutput).toMatch(
'Error: Route /routes/next-url/error with `dynamic = "error"` couldn\'t be rendered statically because it accessed `nextUrl.toString`.'
)
})
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const GET = async (request) => {
try {
const body = JSON.stringify({ pathname: request.nextUrl.toString() })
return new Response(body, {
headers: {
'content-type': 'application/json',
},
})
} catch (err) {
console.log('Caught Error:', err.message)
return new Response(null, { status: 500 })
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const GET = async (request) => {
try {
const body = JSON.stringify({ url: request.url })
return new Response(body, {
headers: {
'content-type': 'application/json',
},
})
} catch (err) {
console.log('Caught Error:', err.message)
return new Response(null, { status: 500 })
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const dynamic = 'error'

export const GET = async (request) => {
return new Response(
JSON.stringify({ query: request.formData.get('query') }),
{
headers: {
'content-type': 'application/json',
},
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const dynamic = 'error'

export const GET = async (request) => {
return new Response(
JSON.stringify({ pathname: request.nextUrl.toString() }),
{
headers: {
'content-type': 'application/json',
},
}
)
}

0 comments on commit ea56c8f

Please sign in to comment.