Gestion des erreurs

Les erreurs peuvent être divisées en deux catégories : erreurs attendues et exceptions non capturées. Cette page vous expliquera comment gérer ces erreurs dans votre application Next.js.

Gestion des erreurs attendues

Les erreurs attendues sont celles qui peuvent survenir lors du fonctionnement normal de l'application, comme celles provenant de la validation côté serveur de formulaires ou de requêtes échouées. Ces erreurs doivent être gérées explicitement et renvoyées au client.

Fonctions serveur

Vous pouvez utiliser le hook useActionState pour gérer les erreurs attendues dans les Fonctions serveur.

Pour ces erreurs, évitez d'utiliser des blocs try/catch et de lancer des erreurs. Modélisez plutôt les erreurs attendues comme des valeurs de retour.

'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' }
  }
}

Vous pouvez passer votre action au hook useActionState et utiliser l'état (state) retourné pour afficher un message d'erreur.

'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>
  )
}

Composants serveur

Lors de la récupération de données dans un composant serveur, vous pouvez utiliser la réponse pour afficher conditionnellement un message d'erreur ou effectuer une redirection.

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

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

  return '...'
}

Not found

Vous pouvez appeler la fonction notFound dans un segment de route et utiliser le fichier not-found.js pour afficher une interface utilisateur 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>
}

Gestion des exceptions non capturées

Les exceptions non capturées sont des erreurs inattendues qui indiquent des bugs ou des problèmes qui ne devraient pas survenir pendant le flux normal de votre application. Celles-ci doivent être gérées en lançant des erreurs, qui seront ensuite capturées par les limites d'erreur (error boundaries).

Limites d'erreur imbriquées

Next.js utilise des limites d'erreur pour gérer les exceptions non capturées. Les limites d'erreur capturent les erreurs dans leurs composants enfants et affichent une interface de repli au lieu de l'arborescence de composants qui a planté.

Créez une limite d'erreur en ajoutant un fichier error.js dans un segment de route et en exportant un composant React :

'use client' // Les limites d'erreur doivent être des composants client

import { useEffect } from 'react'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    // Enregistrez l'erreur dans un service de reporting
    console.error(error)
  }, [error])

  return (
    <div>
      <h2>Something went wrong!</h2>
      <button
        onClick={
          // Tentative de récupération en re-rendant le segment
          () => reset()
        }
      >
        Try again
      </button>
    </div>
  )
}

Les erreurs remonteront jusqu'à la limite d'erreur parente la plus proche. Cela permet une gestion granulaire des erreurs en plaçant des fichiers error.tsx à différents niveaux dans la hiérarchie des routes.

Nested Error Component Hierarchy

Erreurs globales

Bien que moins courantes, vous pouvez gérer les erreurs dans la mise en page racine en utilisant le fichier global-error.js, situé dans le répertoire racine de l'application, même en utilisant l'internationalisation. L'interface utilisateur d'erreur globale doit définir ses propres balises <html> et <body>, car elle remplace la mise en page ou le modèle racine lorsqu'elle est active.

'use client' // Les limites d'erreur doivent être des composants client

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

On this page