Files
Jiwon ChoiandGitHub 74ce6b2e2f Reapply "Stabilize catchError and retry by removing unstable_ prefix" (#94623)
### What?

Reverts #94617, which had reverted #94610. This re-lands the
stabilization of the `catchError` API and the `retry` error prop by
removing their `unstable_` prefix across source, docs, and tests.

### Why?

#94610 was reverted in #94617 to unblock another change. This re-applies
it now that it is no longer blocked.

### How?

`git revert` of the revert commit. The repo's custom errors.json merge
driver handled the error registry: the original codes `1324`/`1325` had
been reclaimed by `instant` errors after the revert, so the reintroduced
messages were minted as new codes `1360` (`retry()` can only be used in
the App Router) and `1361` (`catchError` can only be used in Client
Components), keeping errors.json append-only.

The docs changelog adds `v16.3.0 | catchError became stable.` while
retaining the historical `v16.2.0 | unstable_catchError introduced.`
row.

### Verification

- `pnpm update-error-codes` (check_error_codes passes; errors.json in
sync)
- `pnpm build` (full JS build, exit 0)
- `pnpm --filter=next types` (exit 0)
- Not run: Rust/cargo build (`react_server_components.rs` change is a
one-line allow-list string revert; left to CI)

<!-- NEXT_JS_LLM_PR -->
2026-06-09 16:11:44 -07:00

38 lines
753 B
TypeScript

'use client'
import { useState } from 'react'
import type { ErrorInfo } from 'next/error'
import { catchError } from 'next/error'
function Inner() {
const [clicked, setClicked] = useState(false)
if (clicked) {
// eslint-disable-next-line no-throw-literal -- testing bad values on purpose
throw null
}
return (
<button
id="error-trigger-button"
onClick={() => {
setClicked(true)
}}
>
Trigger Error!
</button>
)
}
function ErrorFallback(_props: {}, { error }: ErrorInfo) {
return <p id="error-boundary-message">{`An error occurred: ${error}`}</p>
}
const Wrapped = catchError(ErrorFallback)
export default function Page() {
return (
<Wrapped>
<Inner />
</Wrapped>
)
}