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 ?
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
:
- Supprimez l'icône de chargement de la page.
- Fournissez un message utile qui explique ce qui s'est mal passé et quelles options l'utilisateur peut prendre.
- Présentez un bouton "Réessayer" à l'utilisateur en fonction des options disponibles.
- 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 entre200
et299
. - 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.