Reword PPR caught bail out to avoid "postpone" terminology (#58223)
The "postpone" terminology is internal to React and can be used for more things than just this. It's also a mechanism we may or may not rely on. --------- Co-authored-by: Zack Tanner <zacktanner@gmail.com>
This commit is contained in:
parent
d68bbd7af7
commit
2f68e62d30
6 changed files with 40 additions and 23 deletions
27
errors/ppr-caught-error.mdx
Normal file
27
errors/ppr-caught-error.mdx
Normal file
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
title: Static Bail Out Caught
|
||||
---
|
||||
|
||||
## Why This Error Occurred
|
||||
|
||||
When Partial Prerendering (PPR) is enabled, using APIs that opt into Dynamic Rendering like `cookies`, `headers`, or `fetch` (such as with `cache: 'no-store'` or `revalidate: 0`) will cause React to throw a special error object to know which part of the page cannot be statically generated - while still letting the rest of it be partially static. If you catch this error, it is not safe for us to generate any static data, and your build will fail.
|
||||
|
||||
## Possible Ways to Fix It
|
||||
|
||||
- Ensure that you are not wrapping Next.js APIs that opt into dynamic rendering in a `try/catch` block.
|
||||
- If you do wrap these APIs in a try/catch, make sure you re-throw the original error so it can be caught by Next.js.
|
||||
- Alternatively, insert [`unstable_noStore()`](docs/app/api-reference/functions/unstable_noStore) before the try/catch.
|
||||
|
||||
```js
|
||||
import { unstable_noStore } from 'next/cache'
|
||||
|
||||
async function fetchData() {
|
||||
unstable_noStore() // opt out before we even get to the try/catch
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
...
|
||||
} catch (x) {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
title: Static Generation Postpone Error
|
||||
---
|
||||
|
||||
## Why This Error Occurred
|
||||
|
||||
When Partial Prerendering (PPR) is enabled, using APIs that opt into Dynamic Rendering like `cookies`, `headers`, or `fetch` (such as with `cache: 'no-store'` or `revalidate: 0`) will cause Next.js to throw a special error to know which part of the page cannot be statically generated. If you catch this error, we will not be able to generate any static data, and your build will fail.
|
||||
|
||||
## Possible Ways to Fix It
|
||||
|
||||
- Ensure that you are not wrapping Next.js APIs that opt into dynamic rendering in a `try/catch` block.
|
||||
- If you do wrap these APIs in a try/catch, make sure you re-throw the original error so it can be caught by Next.js.
|
||||
- Alternatively, insert [`unstable_noStore()`](docs/app/api-reference/functions/unstable_noStore) before the try/catch.
|
|
@ -22,8 +22,8 @@ export function maybePostpone(
|
|||
staticGenerationStore.postponeWasTriggered = true
|
||||
|
||||
React.unstable_postpone(
|
||||
`This page needs to opt out of static rendering at this point because it used ` +
|
||||
`${reason}. React throws this special object to bail out. It should not be caught ` +
|
||||
`by your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-postpone-error`
|
||||
`This page needs to bail out of prerendering at this point because it used ${reason}. ` +
|
||||
`React throws this special object to indicate where. It should not be caught by ` +
|
||||
`your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error`
|
||||
)
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ export const staticGenerationBailout: StaticGenerationBailout = (
|
|||
link: 'https://nextjs.org/docs/messages/dynamic-server-error',
|
||||
})
|
||||
|
||||
maybePostpone(staticGenerationStore, message)
|
||||
maybePostpone(staticGenerationStore, reason)
|
||||
|
||||
// As this is a bailout, we don't want to revalidate, so set the revalidate
|
||||
// to 0.
|
||||
|
|
|
@ -1029,7 +1029,10 @@ async function renderToHTMLOrFlightImpl(
|
|||
// as we won't be able to generate the static part
|
||||
warn('')
|
||||
error(
|
||||
`Postpone signal was caught while rendering ${urlPathname}. Check to see if you're try/catching a Next.js API such as headers / cookies, or a fetch with "no-store". Learn more: https://nextjs.org/docs/messages/ppr-postpone-error`
|
||||
`Prerendering ${urlPathname} needs to partially bail out because something dynamic was used. ` +
|
||||
`React throws a special object to indicate where we need to bail out but it was caught ` +
|
||||
`by a try/catch or a Promise was not awaited. These special objects should not be caught ` +
|
||||
`by your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error`
|
||||
)
|
||||
|
||||
if (capturedErrors.length > 0) {
|
||||
|
|
|
@ -23,14 +23,14 @@ describe('ppr build errors', () => {
|
|||
describe('when a postpone call was made but missing postpone data', () => {
|
||||
it('should fail the build', async () => {
|
||||
expect(stderr).toContain(
|
||||
'Postpone signal was caught while rendering /. Check to see if you\'re try/catching a Next.js API such as headers / cookies, or a fetch with "no-store".'
|
||||
'Prerendering / needs to partially bail out because something dynamic was used. '
|
||||
)
|
||||
})
|
||||
|
||||
it('should fail the build & surface any errors that were thrown by user code', async () => {
|
||||
// in the case of catching a postpone and throwing a new error, we log the error that the user threw to help with debugging
|
||||
expect(stderr).toContain(
|
||||
'Postpone signal was caught while rendering /re-throwing-error. Check to see if you\'re try/catching a Next.js API such as headers / cookies, or a fetch with "no-store".'
|
||||
'Prerendering /re-throwing-error needs to partially bail out because something dynamic was used. '
|
||||
)
|
||||
expect(stderr).toContain(
|
||||
'The following error was thrown during build, and may help identify the source of the issue:'
|
||||
|
@ -57,7 +57,7 @@ describe('ppr build errors', () => {
|
|||
describe('when a postpone call was made but missing postpone data', () => {
|
||||
it('should fail the build', async () => {
|
||||
expect(stderr).toContain(
|
||||
'Postpone signal was caught while rendering /no-suspense-boundary. Check to see if you\'re try/catching a Next.js API such as headers / cookies, or a fetch with "no-store".'
|
||||
'Prerendering /no-suspense-boundary needs to partially bail out because something dynamic was used. '
|
||||
)
|
||||
|
||||
// the regular pre-render error should not be thrown as well, as we've already logged a more specific error
|
||||
|
@ -69,7 +69,7 @@ describe('ppr build errors', () => {
|
|||
it('should fail the build & surface any errors that were thrown by user code', async () => {
|
||||
// in the case of catching a postpone and throwing a new error, we log the error that the user threw to help with debugging
|
||||
expect(stderr).toContain(
|
||||
'Postpone signal was caught while rendering /no-suspense-boundary-re-throwing-error. Check to see if you\'re try/catching a Next.js API such as headers / cookies, or a fetch with "no-store".'
|
||||
'Prerendering /no-suspense-boundary-re-throwing-error needs to partially bail out because something dynamic was used. '
|
||||
)
|
||||
expect(stderr).toContain(
|
||||
'The following error was thrown during build, and may help identify the source of the issue:'
|
||||
|
@ -89,7 +89,7 @@ describe('ppr build errors', () => {
|
|||
describe('when a postpone call is caught and logged it should', () => {
|
||||
it('should include a message telling why', async () => {
|
||||
expect(stdout).toContain(
|
||||
"Logged error: This page needs to opt out of static rendering at this point because it used Page couldn't be rendered statically because it used `cookies`."
|
||||
"Logged error: This page needs to bail out of prerendering at this point because it used Page couldn't be rendered statically because it used `cookies`."
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue