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 offrant un niveau de fonctionnalité raisonnable, résilient 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.
Anticiper les erreurs réseau potentielles
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 utilisez l'outil de récupération, vous pouvez facilement prendre en compte le chemin du succès à partir duquel l'utilisateur a mis en ligne la vidéo. Cependant, il existe d'autres chemins qui ne sont pas aussi fluides, mais pour lesquels les développeurs Web doivent planifier. De tels chemins (ou mécontents) 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, au format JPEG) au lieu d'un fichier vidéo.
- L'utilisateur commence à importer le mauvais fichier vidéo. Ensuite, au milieu de la mise en ligne, l'utilisateur spécifie le fichier vidéo à mettre en ligne.
- 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 sur le 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 et se produisent dans le monde réel. Vous avez peut-être déjà rencontré de tels exemples dans le passé. Prenons un exemple dans chacune des catégories précédentes et discutons des 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 le processus ?
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
:
- Supprimez la roue de sélection de la page.
- Fournissez des messages utiles qui expliquent ce qui s'est mal passé et les options disponibles pour l'utilisateur.
- En fonction des options disponibles, présentez un bouton "Réessayer" à l'utilisateur.
- 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, pendant que vous diagnostiquez l'erreur que vous avez consignée, vous pouvez écrire un scénario test afin de détecter ce type d'erreur avant que les utilisateurs ne s'en aperçoivent. 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 par le code d'état HTTP 429 Too Many Requests
. Fait intéressant, la réponse n'atteint pas le bloc catch
. Parmi d'autres codes d'état, le code d'état 404 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 entre200
et299
. - 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 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 pour comprendre les codes d'état de réponse HTTP potentiels. Les développeurs backend, les opérations de développement et les ingénieurs de service peuvent parfois fournir des informations uniques sur des cas extrêmes possibles que vous n'aviez 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 JSON. Dans le code suivant, une requête réseau est envoyée à un service de test HTTP qui renvoie une chaîne HTML en tant que 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 de transfert peuvent varier, mais cela dépend finalement 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.
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 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 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 les fonctionnalités et l'interface utilisateur pour différents scénarios.