Cómo manejar errores

Los errores se pueden dividir en dos categorías: errores esperados y excepciones no capturadas. Esta página le guiará sobre cómo puede manejar estos errores en su aplicación Next.js.

Manejo de errores esperados

Los errores esperados son aquellos que pueden ocurrir durante el funcionamiento normal de la aplicación, como los de validación de formularios del lado del servidor (server-side form validation) o solicitudes fallidas. Estos errores deben manejarse explícitamente y devolverse al cliente.

Funciones del servidor (Server Functions)

Puede usar el hook useActionState para manejar errores esperados en Funciones del servidor (Server Functions).

Para estos errores, evite usar bloques try/catch y lanzar errores. En su lugar, modele los errores esperados como valores de retorno.

'use server'

export async function createPost(prevState: any, formData: FormData) {
  const title = formData.get('title')
  const content = formData.get('content')

  const res = await fetch('https://api.vercel.app/posts', {
    method: 'POST',
    body: { title, content },
  })
  const json = await res.json()

  if (!res.ok) {
    return { message: 'Failed to create post' }
  }
}

Puede pasar su acción al hook useActionState y usar el state devuelto para mostrar un mensaje de error.

'use client'

import { useActionState } from 'react'
import { createPost } from '@/app/actions'

const initialState = {
  message: '',
}

export function Form() {
  const [state, formAction, pending] = useActionState(createPost, initialState)

  return (
    <form action={formAction}>
      <label htmlFor="title">Title</label>
      <input type="text" id="title" name="title" required />
      <label htmlFor="content">Content</label>
      <textarea id="content" name="content" required />
      {state?.message && <p aria-live="polite">{state.message}</p>}
      <button disabled={pending}>Create Post</button>
    </form>
  )
}

Componentes del servidor (Server Components)

Al obtener datos dentro de un Componente del servidor (Server Component), puede usar la respuesta para renderizar condicionalmente un mensaje de error o redirect.

export default async function Page() {
  const res = await fetch(`https://...`)
  const data = await res.json()

  if (!res.ok) {
    return 'There was an error.'
  }

  return '...'
}

No encontrado (Not found)

Puede llamar a la función notFound dentro de un segmento de ruta y usar el archivo not-found.js para mostrar una interfaz de usuario 404.

import { getPostBySlug } from '@/lib/posts'

export default async function Page({ params }: { params: { slug: string } }) {
  const { slug } = await params
  const post = getPostBySlug(slug)

  if (!post) {
    notFound()
  }

  return <div>{post.title}</div>
}

Manejo de excepciones no capturadas

Las excepciones no capturadas son errores inesperados que indican bugs o problemas que no deberían ocurrir durante el flujo normal de su aplicación. Estos deben manejarse lanzando errores, que luego serán capturados por los límites de error (error boundaries).

Límites de error anidados (Nested error boundaries)

Next.js usa límites de error (error boundaries) para manejar excepciones no capturadas. Los límites de error capturan errores en sus componentes hijos y muestran una interfaz de usuario alternativa en lugar del árbol de componentes que falló.

Cree un límite de error agregando un archivo error.js dentro de un segmento de ruta y exportando un componente React:

'use client' // Los límites de error deben ser Componentes de Cliente (Client Components)

import { useEffect } from 'react'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    // Registrar el error en un servicio de reporte de errores
    console.error(error)
  }, [error])

  return (
    <div>
      <h2>Something went wrong!</h2>
      <button
        onClick={
          // Intentar recuperarse volviendo a renderizar el segmento
          () => reset()
        }
      >
        Try again
      </button>
    </div>
  )
}

Los errores subirán al límite de error padre más cercano. Esto permite un manejo de errores granular colocando archivos error.tsx en diferentes niveles de la jerarquía de rutas.

Nested Error Component Hierarchy

Errores globales

Aunque menos común, puede manejar errores en el diseño raíz usando el archivo global-error.js, ubicado en el directorio raíz de la aplicación, incluso cuando se utiliza internacionalización. La interfaz de usuario de error global debe definir sus propias etiquetas <html> y <body>, ya que reemplaza el diseño raíz o plantilla cuando está activa.

'use client' // Los límites de error deben ser Componentes de Cliente (Client Components)

export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    // global-error debe incluir etiquetas html y body
    <html>
      <body>
        <h2>Something went wrong!</h2>
        <button onClick={() => reset()}>Try again</button>
      </body>
    </html>
  )
}

On this page