Capítulo 181 de 456

unstable_rethrow

Core Idea

Evita capturar erros internos do Next.js (como notFound(), redirect()) quando você envolve código em try/catch para tratar erros da própria aplicação.

Key Concepts

  • unstable_rethrow(err): chamado no topo do bloco catch (ou num .catch de Promise), repassa erros internos controlados pelo framework antes de tratar o resto.
  • APIs que lançam erros a serem repassados: notFound(), redirect(), permanentRedirect().
  • Request-time APIs que também lançam (quando a rota exige estático): cookies, headers, searchParams, fetch(..., { cache: 'no-store' }), fetch(..., { next: { revalidate: 0 } }).

Code Examples

// Sem unstable_rethrow: notFound() é engolido pelo catch, not-found.js não renderiza
import { notFound } from 'next/navigation'

export default async function Page() {
  try {
    const post = await fetch('https://.../posts/1').then((res) => {
      if (res.status === 404) notFound()
      if (!res.ok) throw new Error(res.statusText)
      return res.json()
    })
  } catch (err) {
    console.error(err)
  }
}
  • O que demonstra: bug comum — notFound() capturado por engano dentro de um catch genérico.
// Com unstable_rethrow: erro interno passa, erro de app é tratado
import { notFound, unstable_rethrow } from 'next/navigation'

export default async function Page() {
  try {
    const post = await fetch('https://.../posts/1').then((res) => {
      if (res.status === 404) notFound()
      if (!res.ok) throw new Error(res.statusText)
      return res.json()
    })
  } catch (err) {
    unstable_rethrow(err)
    console.error(err)
  }
}
  • O que demonstra: forma correta de deixar o erro interno do Next.js passar, tratando só os erros reais da aplicação.

Anti-patterns

  • try/catch genérico envolvendo notFound()/redirect() sem unstable_rethrow: suprime a navegação/erro esperado silenciosamente.
  • Fazer cleanup de recursos depois da chamada a unstable_rethrow: código após ela só roda se não for erro interno — cleanup deve ficar antes ou em bloco finally.

Key Takeaways

  1. Só é necessário se o catch pode receber tanto erros de aplicação quanto exceções controladas pelo framework (redirect/notFound/etc).
  2. Alternativa: encapsular chamadas que lançam esses erros e deixar o caller tratar a exceção, evitando unstable_rethrow de todo.
  3. Chame sempre como primeira linha do catch.

Connects To

  • notFound: uma das exceções que precisa ser repassada.
  • redirect / permanentRedirect: idem.