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

Cet article présente quelques approches de gestion des erreurs lors de l'utilisation de 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 à distance, votre page Web est soumise à diverses erreurs réseau potentielles.

Les sections suivantes décrivent les erreurs potentielles et expliquent comment écrire du code qui offre un niveau de fonctionnalité adapté et résistant aux erreurs et aux conditions réseau inattendues. Le code résilient permet de satisfaire vos utilisateurs et de maintenir un niveau de service standard pour votre site Web.

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

Lorsque vous travaillez avec Fetch, il est facile de considérer le parcours heureux où l'utilisateur importe avec succès la vidéo. Cependant, il existe d'autres chemins qui ne sont pas aussi fluides, mais pour lesquels les développeurs Web doivent planifier. Ces parcours (décevants) 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, à mi-chemin de l'importation, l'utilisateur spécifie le bon fichier vidéo à importer.
  • L'utilisateur clique accidentellement sur "Annuler la mise en ligne" pendant la mise en ligne de la vidéo.

Exemples de changements environnementaux

  • La connexion Internet est hors service pendant la mise en ligne 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 de partage de vidéos ne peut pas gérer de nom de fichier contenant un espace. Au lieu de "My Travels.mp4", il attend un nom tel que "My_Travels.mp4" ou "MyTravels.mp4".
  • Le site de partage de vidéos ne peut pas importer de vidéo dont la taille dépasse la taille maximale acceptable.
  • Le site de partage de vidéos n'est pas compatible avec le codec vidéo de la vidéo mise en ligne.

Ces exemples peuvent se produire dans le monde réel. Vous avez peut-être déjà rencontré de tels exemples ! Prenons un exemple dans chacune des catégories précédentes et examinons 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é ?
  • Que l'utilisateur s'attend-il à voir se produire dans cet exemple ?
  • Comment pouvons-nous améliorer le processus ?
Action L'utilisateur commence à importer le mauvais fichier vidéo. Ensuite, à mi-chemin de l'importation, l'utilisateur spécifie le bon fichier vidéo à importer.
Que se passe-t-il par défaut ? Le fichier d'origine continue d'être importé en arrière-plan pendant l'importation du nouveau fichier.
Ce à quoi l'utilisateur s'attend L'utilisateur s'attend à ce que l'importation d'origine s'arrête afin qu'aucune bande passante Internet supplémentaire ne soit gaspillée.
Ce qui peut être amélioré JavaScript annule la requête de récupération du fichier d'origine avant que le nouveau fichier ne commence à être importé.
Action L'utilisateur perd sa connexion Internet pendant la mise en ligne de la vidéo.
Que se passe-t-il par défaut ? La barre de progression de l'importation semble bloquée à 50%. À terme, l'API Fetch expire et les données importées sont supprimées. Lorsque la connexion Internet est rétablie, l'utilisateur doit réimporter son fichier.
Ce à quoi l'utilisateur s'attend L'utilisateur s'attend à être informé lorsque son fichier ne peut pas être importé et à ce que l'importation soit automatiquement reprise à 50% lorsqu'il est de nouveau en ligne.
Ce qui peut être amélioré La page d'importation informe l'utilisateur des problèmes de connectivité Internet et le rassure en lui indiquant que l'importation reprendra lorsque la connectivité Internet sera rétablie.
Action Le site de partage de vidéos ne peut pas gérer de nom de fichier contenant un espace. Au lieu de "My Travels.mp4", il attend des noms tels que "My_Travels.mp4" ou "MyTravels.mp4".
Que se passe-t-il 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%", le message suivant s'affiche: "Veuillez réessayer."
Ce à quoi l'utilisateur s'attend L'utilisateur s'attend à être informé des limites concernant les noms de fichiers avant le début de l'importation, ou au moins dans la première seconde de l'importation.
Ce qui peut être amélioré Idéalement, le service de partage de vidéos accepte les noms de fichiers avec espaces. Vous pouvez également informer l'utilisateur des limites concernant les noms de fichiers avant le début de l'importation. Le service de partage de vidéos doit également refuser l'importation et afficher un message d'erreur détaillé.

Gérer les erreurs avec l'API Fetch

Notez que les exemples de code suivants utilisent await de niveau supérieur (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 intercepter les erreurs générées 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 un spinner (une interface utilisateur courante qui représente une sorte de progression) est présenté à l'utilisateur, vous pouvez effectuer les actions suivantes dans un bloc catch:

  1. Supprimez la roue de sélection de la page.
  2. Fournissez des messages utiles qui expliquent ce qui s'est mal passé et les options disponibles pour l'utilisateur.
  3. En fonction des options disponibles, présentez un bouton "Réessayer" à l'utilisateur.
  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 ultérieurement.
try {
 
const response = await fetch('https://website');
} catch (error) {
 
// TypeError: Failed to fetch
  console
.log('There was an error', error);
}

À un stade ultérieur, lorsque vous diagnostiquerez l'erreur que vous avez enregistrée, vous pourrez écrire un cas de test pour détecter une telle erreur avant que vos utilisateurs ne s'aperçoivent qu'un problème est survenu. Selon l'erreur, il peut s'agir d'un test unitaire, d'intégration ou d'acceptation.

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. Fait intéressant, la réponse n'atteint pas le bloc catch. Un état 404, parmi 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 a bien été renvoyé, vous pouvez utiliser l'une des options suivantes:

  • Utilisez la propriété Response.ok pour déterminer si le code d'état se situe entre 200 et 299.
  • Utilisez la propriété Response.status pour déterminer si la réponse a réussi.
  • Utilisez d'autres métadonnées, telles que Response.headers, pour évaluer si la réponse a réussi.
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 pour 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 insights uniques sur les cas particuliers que vous n'auriez peut-être pas anticipés.

En cas d'erreur lors de l'analyse de la réponse réseau

Cet exemple de code illustre un autre type d'erreur pouvant survenir lors de l'analyse d'un corps de réponse. L'interface Response propose des méthodes pratiques pour analyser différents types de données, tels que du texte ou du JSON. Dans le code suivant, une requête réseau est envoyée à un service de test HTTP qui renvoie une chaîne HTML comme corps de réponse. Toutefois, une tentative d'analyse du corps de la réponse en tant que JSON est effectuée, 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 ne casse pas la page Web pour l'utilisateur.

Imaginons le scénario suivant: vous disposez d'une ressource distante qui renvoie une réponse JSON valide et qui est correctement analysée avec la méthode Response.json(). Il est possible que le service soit indisponible. Une fois la mise à jour terminée, un 500 Internal Server Error est renvoyé. Si les techniques de gestion des erreurs appropriées ne sont pas utilisées lors de l'analyse du fichier JSON, la page peut ne pas s'afficher 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 AbortController pour annuler une requête en cours. Une requête en cours est une requête réseau qui a commencé, mais qui n'est pas terminée.

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

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 fonctionner. Pour chaque scénario, assurez-vous de disposer d'un plan de secours approprié pour l'utilisateur. Pour une requête de récupération, posez-vous les questions suivantes:

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

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