Implémenter la gestion des erreurs lors de l'utilisation de l'API Fetch

Cet article présente certaines approches de gestion des erreurs lorsque vous utilisez l'API Fetch. L'API Fetch vous permet d'envoyer une requête à une ressource réseau distante. Lorsque vous effectuez un appel réseau distant, votre page Web est soumise à diverses erreurs réseau potentielles.

Les sections suivantes décrivent les erreurs potentielles et décrivent comment écrire du code offrant un niveau de fonctionnalité judicieux, résistant aux erreurs et aux conditions de réseau inattendues. Un code résistant assure la satisfaction de vos utilisateurs et maintient un niveau de service standard pour votre site Web.

Anticipez les éventuelles erreurs réseau

Cette section décrit un scénario dans lequel l'utilisateur crée une vidéo nommée "My Travels.mp4", puis tente de la mettre en ligne sur un site Web de partage de vidéos.

Avec l'outil Fetch, vous pouvez facilement prendre en compte la solution réussie, qui consiste à mettre en ligne la vidéo. Cependant, d'autres chemins ne sont pas aussi faciles, mais doivent être planifiés par les développeurs Web. De tels chemins (malheureux) peuvent se produire en raison d'une erreur de l'utilisateur, de conditions environnementales inattendues ou d'un bug sur le site Web de partage de vidéos.

Exemples d'erreurs utilisateur

  • L'utilisateur importe un fichier image (par exemple, JPEG) au lieu d'un fichier vidéo.
  • L'utilisateur commence à importer le mauvais fichier vidéo. Ensuite, au cours de la mise en ligne, l'utilisateur spécifie le bon fichier vidéo à mettre en ligne.
  • L'utilisateur clique par erreur sur "Annuler l'importation" pendant l'importation de la vidéo.

Exemples de changements environnementaux

  • La connexion Internet est coupée pendant l'importation de la vidéo.
  • Le navigateur redémarre pendant la mise en ligne de la vidéo.
  • Les serveurs du site Web de partage de vidéos redémarrent pendant la mise en ligne de la vidéo.

Exemples d'erreurs liées au site Web de partage de vidéos

  • Le site Web de partage de vidéos ne peut pas gérer un nom de fichier comportant un espace. Au lieu de "My Travels.mp4", il attend un nom tel que "My_Travels.mp4" ou "MyTravels.mp4".
  • Le site Web de partage de vidéos ne peut pas mettre en ligne une vidéo dont la taille dépasse la limite autorisée.
  • Le site Web de partage de vidéos ne prend pas en charge le codec vidéo de la vidéo mise en ligne.

Ces exemples peuvent se produire et se produisent dans le monde réel. Vous avez peut-être rencontré de tels exemples dans le passé ! Choisissons un exemple dans chacune des catégories précédentes et abordons les points suivants:

  • Quel est le comportement par défaut si le service de partage de vidéos ne peut pas gérer l'exemple donné ?
  • À quoi l'utilisateur s'attend-il dans l'exemple ?
  • Comment pouvons-nous améliorer ce processus ?
Action L'utilisateur commence à importer le mauvais fichier vidéo. Ensuite, au cours de la mise en ligne, l'utilisateur spécifie le bon fichier vidéo à mettre en ligne.
Ce qui se passe par défaut L'importation du fichier d'origine se poursuit en arrière-plan pendant que le nouveau fichier est importé en même temps.
Objectifs de l'utilisateur L'utilisateur s'attend à ce que l'importation d'origine s'arrête pour éviter de gaspiller de la bande passante Internet supplémentaire.
Ce qui peut être amélioré JavaScript annule la demande Fetch du fichier d'origine avant le début de l'importation du nouveau fichier.
Action L'utilisateur perd sa connexion Internet au cours de la mise en ligne de la vidéo.
Ce qui se passe par défaut La barre de progression de l'importation semble bloquée sur 50%. L'API Fetch rencontre un délai d'inactivité et les données importées sont supprimées. Lorsque la connexion Internet est rétablie, l'utilisateur doit importer à nouveau son fichier.
Objectifs de l'utilisateur L'utilisateur s'attend à recevoir une notification lorsque son fichier ne peut pas être importé. Il s'attend à ce que l'importation reprenne automatiquement à 50% lorsqu'il se reconnecte.
Ce qui peut être amélioré La page d'importation informe l'utilisateur des problèmes de connectivité Internet et le rassure sur le fait que l'importation reprendra une fois la connexion rétablie.
Action Le site Web de partage de vidéos ne peut pas gérer un nom de fichier comportant un espace. Au lieu de "Mes voyages.mp4", le fichier doit être nommé "Mes_Voyages.mp4" ou "MesVoyages.mp4".
Ce qui se passe par défaut L'utilisateur doit attendre la fin de l'importation. Une fois le fichier importé et que la barre de progression indique "100%", cette barre affiche le message "Veuillez réessayer".
Objectifs de l'utilisateur L'utilisateur s'attend à être informé des limites du nom de fichier avant le début de l'importation, ou au moins pendant la première seconde.
Ce qui peut être amélioré Idéalement, le service de partage de vidéos prend en charge les noms de fichiers contenant des espaces. Vous pouvez également signaler à l'utilisateur les limites du nom de fichier avant de lancer l'importation. Sinon, le service de partage de vidéos doit rejeter la mise en ligne avec un message d'erreur détaillé.

Gérer les erreurs avec l'API Fetch

Notez que les exemples de code suivants utilisent la version de premier niveau await (compatibilité avec les navigateurs), car cette fonctionnalité peut simplifier votre code.

Lorsque l'API Fetch génère des erreurs

Cet exemple utilise une instruction de bloc try/catch pour identifier toute erreur générée dans le bloc try. Par exemple, si l'API Fetch ne peut pas récupérer la ressource spécifiée, une erreur est générée. Dans un bloc catch comme celui-ci, veillez à offrir une expérience utilisateur pertinente. Si une icône de chargement (une interface utilisateur courante représentant une progression) est présentée à l'utilisateur, vous pouvez effectuer les actions suivantes dans un bloc catch:

  1. Supprimez l'icône de chargement de la page.
  2. Fournissez un message utile qui explique ce qui s'est mal passé et quelles options l'utilisateur peut prendre.
  3. Présentez un bouton "Réessayer" à l'utilisateur en fonction des options disponibles.
  4. En arrière-plan, envoyez les détails de l'erreur à votre service de suivi des erreurs ou au backend. Cette action consigne l'erreur afin qu'elle puisse être diagnostiquée à un stade ultérieur.
try {
  const response = await fetch('https://website');
} catch (error) {
  // TypeError: Failed to fetch
  console.log('There was an error', error);
}

Par la suite, le temps de diagnostiquer l'erreur consignée, vous pourrez écrire un scénario test afin de détecter ce type d'erreur avant que vos utilisateurs ne se rendent compte qu'il s'agit d'un problème. Selon l'erreur, il peut s'agir d'un test unitaire, d'un test d'intégration ou d'un test de validation.

Lorsque le code d'état du réseau représente une erreur

Cet exemple de code envoie une requête à un service de test HTTP qui répond toujours avec le code d'état HTTP 429 Too Many Requests. Il est intéressant de noter que la réponse n'atteint pas le bloc catch. Un code d'état 404, comme d'autres codes d'état, ne renvoie pas d'erreur réseau, mais se résout normalement.

Pour vérifier que le code d'état HTTP aboutit, vous pouvez utiliser l'une des options suivantes:

  • Utilisez la propriété Response.ok pour déterminer si le code d'état est compris entre 200 et 299.
  • Utilisez la propriété Response.status pour déterminer si la réponse a abouti.
  • Utilisez d'autres métadonnées, telles que Response.headers, pour déterminer si la réponse a abouti.
let response;

try {
  response = await fetch('https://httpbin.org/status/429');
} catch (error) {
  console.log('There was an error', error);
}

// Uses the 'optional chaining' operator
if (response?.ok) {
  console.log('Use the response here!');
} else {
  console.log(`HTTP Response Code: ${response?.status}`)
}

Il est recommandé de collaborer avec les membres de votre organisation et de votre équipe afin de comprendre les codes d'état de réponse HTTP potentiels. Les développeurs backend, les développeurs d'opérations et les ingénieurs de service peuvent parfois fournir des informations uniques sur des cas spéciaux que vous n'aviez peut-être pas anticipés.

Lorsqu'une erreur se produit lors de l'analyse de la réponse du réseau

Cet exemple de code illustre un autre type d'erreur qui peut se produire lors de l'analyse du corps d'une réponse. L'interface Response propose des méthodes pratiques pour analyser différents types de données, tels que du texte ou des données JSON. Dans le code suivant, une requête réseau est envoyée à un service de test HTTP qui renvoie une chaîne HTML dans le corps de la réponse. Toutefois, nous tentons d'analyser le corps de la réponse au format JSON, ce qui génère une erreur.

let json;

try {
  const response = await fetch('https://httpbin.org/html');
  json = await response.json();
} catch (error) {
  if (error instanceof SyntaxError) {
    // Unexpected token < in JSON
    console.log('There was a SyntaxError', error);
  } else {
    console.log('There was an error', error);
  }
}

if (json) {
  console.log('Use the JSON here!', json);
}

Vous devez préparer votre code pour qu'il accepte différents formats de réponse et vérifier qu'une réponse inattendue n'interrompt pas la page Web pour l'utilisateur.

Considérons le scénario suivant: vous disposez d'une ressource distante qui renvoie une réponse JSON valide, et elle est analysée avec la méthode Response.json(). Il peut arriver que le service tombe en panne. Une fois en panne, un 500 Internal Server Error est renvoyé. Si les techniques appropriées de gestion des erreurs ne sont pas utilisées lors de l'analyse du fichier JSON, la page risque d'être endommagée pour l'utilisateur, car une erreur non gérée est générée.

Lorsque la requête réseau doit être annulée avant d'être terminée

Cet exemple de code utilise un élément AbortController pour annuler une requête en cours. Une requête en cours de transfert est une requête réseau qui a démarré, mais ne s'est pas terminée.

Les scénarios dans lesquels vous pouvez être amené à annuler une requête en cours peuvent varier, mais cela dépend en fin de compte de votre cas d'utilisation et de votre environnement. Le code suivant montre comment transmettre un AbortSignal à l'API Fetch. Le AbortSignal est associé à un AbortController, et le AbortController inclut une méthode abort(), qui indique au navigateur que la requête réseau doit être annulée.

const controller = new AbortController();
const signal = controller.signal;

// Cancel the fetch request in 500ms
setTimeout(() => controller.abort(), 500);

try {
  const url = 'https://httpbin.org/delay/1';
  const response = await fetch(url, { signal });
  console.log(response);
} catch (error) {
  // DOMException: The user aborted a request.
  console.log('Error: ', error)
}

Conclusion

Un aspect important de la gestion des erreurs consiste à définir les différentes parties qui peuvent mal tourner. Pour chaque scénario, assurez-vous de mettre en place une solution de remplacement appropriée pour l'utilisateur. Concernant une demande d'extraction, posez-vous des questions telles que:

  • Que se passe-t-il en cas de panne du serveur cible ?
  • Que se passe-t-il si Fetch reçoit une réponse inattendue ?
  • Que se passe-t-il en cas d'échec de la connexion Internet de l'utilisateur ?

Selon la complexité de votre page Web, vous pouvez également esquisser un organigramme qui décrit la fonctionnalité et l'interface utilisateur pour différents scénarios.