Comment intercepter des erreurs avec Next.js ?

Publié le 08/07/2024 - Ecrit par Antoine Bourin

4 minutes

La gestion d'erreur d'un composant est intégrée directement dans le routage de l'application Next.js. La création du fichier error.js dans le routage génère automatiquement un composant qui intercepte les potentielles erreurs dans vos pages ou layout.

Ce composant évite que votre interface devienne vide ou incomplète en remplaçant cette partie par une interface que vous aurez choisi. Vous pouvez même vous en servir pour faire remonter ces logs dans vos services de logs comme Sentry.

Comment gérer les erreurs d'une page avec Next.js ?

Pour comprendre comment s'assurer que les erreurs d'une page soient bien gérés pour une page dans le framework, il s'agit d'abord de comprendre comment fonctionne un composant Error Boundary avec React.

Par défaut, lorsqu'un composant React subit une erreur inattendue lors de son rendu, React retire son interface du rendu. Pour éviter ce comportement, vous pouvez encapsuler un ou plusieurs composants par un Error Boundary. Le rôle de ce composant sera d'afficher une interface de remplacement comme par exemple, un message d'erreur.

Avec Next.js, la création d'un tel composant est transparente : la création d'un fichier error.js dans le routage créé un Error Boundary automatiquement. Ce boundary attrapera les erreurs des pages du même segment et des segments inférieurs. Cependant, uniquement les erreurs des layouts de segments inférieurs.

Erreur pages et layouts error.js

Ici, comme expliqué juste avant l'image : les erreurs qui surviendraient des pages seront interceptées car elles se situent au même segment et au segment inférieur de l'error boundary.

Le layout cependant, étant dans le même segment, ne voit pas ses possibles erreurs interceptées. Nous verrons que spécifiquement pour le layout racine (RootLayout), un fichier global-error.js est requis.

Composition du fichier error.js

Le fichier d'erreur doit exporter un composant client. Le rendu de ce composant constituera l'interface de remplacement à afficher en cas d'erreur. Il s'agit du composant de fallback.

Ce composant reçoit deux props : 

  • error : constitue le message d'erreur intercepté. Peut être utilisé pour être envoyé à un service de logs extérieur comme Sentry.
  • reset : fonction qui peut être utilisée pour tenter de re-rendre les composants du segment et tenter de retrouver l'interface original de la page. Peut être appliquée sur un bouton pour permettre à l'utilisateur de retenter un nouvel affichage.

Ce composant Error sera utilisé en remplacement d'une interface en cas d'erreur :

'use client'
// error.js
const Error = ({
  error,
  reset,
}) => {
  return (
    <div>
      <h1>Désolé, une erreur est survenue.</h1>
      <button onClick={() => reset()}>Réessayer</button>
    </div>
  )
}

export default Error;

Voilà le résultat que l'on pourrait obtenir si notre page déclenche une erreur :

Interface de remplacement d'erreur Next.js

Gestion des erreurs d'un layout ou template

La création du fichier error.js créé un Error Boundary qui peut intercepter les erreurs des layouts de segments inférieurs seulement.

Mais alors comment intercepter les erreurs du RootLayout, layout situé à la racine du dossier app du routage de l'application ? 

Utilisation du fichier global-error.js

Pour intercepter les erreurs qui proviendraient du layout principal, aussi appelé RootLayout, l'utilisation du fichier global-error.js est nécessaire.

Le comportement pour ce fichier est similaire à celle du fichier error.js. La seule différence est que, comme il est prévu d'intercepter les erreurs du layout principal, celui-ci doit définir ses propres balises <html> et <body>.

L'exemple est donc quasiment identique à l'exemple du composant d'erreur précédent :

"use client";
// global-error.js

const GlobalError = ({
  error,
  reset,
}) => {
  return (
    <html>
      <body>
        <h1>Désolé, une erreur est survenue.</h1>
        <button onClick={() => reset()}>Réessayer</button>
      </body>
    </html>
  )
}

export default GlobalError;

Vous pouvez combiner l'utilisation du fichier global-error.js et error.js sur le segment principal de votre routage (/app) pour intercepter les erreurs des pages et également de l'ensemble des layouts.

Erreurs de composants serveurs

Pour sécuriser de potentielles informations sensibles et ne pas les rendre accessibles aux utilisateurs, la gestion d'erreur est légèrement différente lorsqu'il s'agit d'erreurs déclenchées depuis des composants serveurs.

Le props error propagé au composant situé dans le fichier error.js ou global-error.js contient un objet avec :

  • message : contient un message générique non représentatif de l'erreur générée (pour éviter de rendre public de potentielles informations qui devraient rester secrètes)
  • digest : contient un ID généré qui peut être utilisé pour retrouver l'erreur dans les logs serveurs de l'application (par exemple depuis Vercel Logs).

Cette sécurisation n'est pas appliquée en mode de développement pour pouvoir débugger facilement.

Intercepter les erreurs de type page non trouvée 404

Par défaut, pour les pages non trouvées, Next.js affiche une page 404 générique pour les utilisateurs de votre application. Le message proposé par défaut est : This page could not be found.

Cette page peut être affichée lorsqu'aucun de vos segments créés dans le routage ne permet d'afficher une page pour l'URL demandée

Fichier de routage not-found.js

Pour remplacer l'interface par défaut proposée lors d'une page 404, vous pouvez créer à la racine de votre dossier app un fichier not-found.js :

import Link from 'next/link'
 
export default function NotFound() {
  return (
    <div>
      <h2>Page non trouvée</h2>
      <p>Aucune ressource n'a pu être trouvée pour votre requête.</p>
      <Link href="/">Accueil</Link>
    </div>
  )
}

Par défaut, ce composant qui vient agir comme interface de remplacement lors d'une page 404, est un composant client.

Si besoin, vous pouvez rendre ce composant async pour pouvoir exécuter des requêtes vers votre base de données ou avec fetch par exemple.

Invoquer une page 404 avec la fonction notFound

Vous pourriez être amené pour certaines pages à vouloir afficher une page 404.

Cela pourrait être le cas par exemple si un segment dynamique products/[id] ne trouverait aucun ID connu dans les données de votre application. Vous pourrez dans ce cas utiliser la fonction notFound pour déclencher une erreur 404 :

// app/products/[id]/page.tsx
const ProductPage({ params }) {
  const product = await fetchProducts(params.id)
 
  if (!product) {
    notFound()
  }
 
  // ...
}

Envie d'en apprendre plus sur Next.js ?

Découvrez une formation Next.js complète :

  • Comprendre et créer un système de routage complet
  • Créer des routes statiques et dynamique
  • Maîtriser le rendu serveur et client
  • Utiliser tous les atouts majeurs proposés par le framework

Plus de 35 heures de contenu vidéo

Plus de 80 cours écrits