Réagissez à la gestion et au signalement des erreurs avec les limites d'erreur et la sentinelle
Dans cet article, nous allons examiner les limites d'erreurs dans React. Nous apprendrons ce qu'ils sont et comment les utiliser pour offrir une meilleure expérience utilisateur, même lorsque quelque chose se casse dans notre application. Nous allons également apprendre à intégrer Sentry pour la surveillance des erreurs en temps réel.
Ce didacticiel s'adresse aux développeurs React de tous les niveaux qui souhaitent commencer à utiliser les limites d'erreur dans leurs applications React.
La seule condition préalable est que vous ayez une certaine familiarité avec les composants de la classe React.
J'utiliserai Yarn comme gestionnaire de packages pour ce projet. Vous trouverez des instructions d'installation pour votre système d'exploitation spécifique sur ici .
Qu'est-ce qu'une limite d'erreur et pourquoi en avons-nous besoin?
Une image, dit-on, vaut mille mots. Pour cette raison, je voudrais parler des limites d'erreur en utilisant – vous l'aurez deviné – des images.
L'illustration ci-dessous montre l'arborescence des composants d'une application React simple. Il a un en-tête, une barre latérale sur la gauche et le composant principal, qui sont tous enveloppés par un composant racine
.

Lors du rendu de ces composants, nous arrivons à quelque chose qui ressemble à l'image ci-dessous.

Dans un monde idéal, nous nous attendrions à voir l'application rendue de cette façon à chaque fois. Mais, malheureusement, nous vivons dans un monde non idéal. Des problèmes (bogues) peuvent apparaître dans le frontend, le backend, la fin du développeur et mille autres extrémités. Le problème pourrait se produire dans l'un de nos trois composants ci-dessus. Lorsque cela se produit, notre application magnifiquement conçue tombe en panne comme un château de cartes.
React encourage la réflexion en termes de composants. Composer plusieurs composants plus petits est mieux que d'avoir un seul composant géant. Travailler de cette façon nous aide à penser à notre application en unités simples. Mais à part cela, ce ne serait pas bien si nous pouvions contenir des erreurs qui pourraient se produire dans l'un des composants? Pourquoi une défaillance d'un seul composant devrait-elle faire tomber toute la maison?
Dans les premiers jours de React, c'était tout à fait le cas. Et pire, parfois, vous ne pouviez même pas comprendre quel était le problème. Le référentiel React sur Github contient certaines de ces erreurs notables ici ici et ici .
React 16 est venu à la rescousse avec le concept d'un «Limite d'erreur». L'idée est simple. Érigez une clôture autour d'un composant pour empêcher tout feu dans ce composant de sortir.
L'illustration ci-dessous montre une arborescence de composants avec un composant
enveloppant le composant . Notez que nous pourrions certainement envelopper les autres composants dans une limite d'erreur si nous le voulions. Nous pourrions même envelopper le composant
dans une limite d'erreur.

Le contour rouge dans l'illustration ci-dessous représente la limite d'erreur lors du rendu de l'application.

Comme nous l'avons vu plus haut, cette ligne rouge empêche les erreurs qui se produisent dans le composant de se répandre et de planter les composants
et
. C'est pourquoi nous avons besoin d'une limite d'erreur.
Maintenant que nous avons une compréhension conceptuelle d'une limite d'erreur, passons maintenant aux aspects techniques.
Qu'est-ce qui fait d'un composant une limite d'erreur?
Comme nous pouvons le voir à partir de notre arborescence de composants, la frontière d'erreur elle-même est un composant React. Selon les documents,
Un composant de classe devient une limite d'erreur s'il définit l'une (ou les deux) des méthodes de cycle de vie
static getDerivedStateFromError ()
oucomponentDidCatch ()
.
] Il y a deux choses à noter ici. Premièrement, seul un composant de classe peut être utilisé comme limite d'erreur. Même si vous écrivez tous vos composants en tant que fonction, vous devez toujours utiliser un composant de classe si vous souhaitez avoir une limite d'erreur. Deuxièmement, il doit définir soit (soit les deux) de getDerivedStateFromError ()
ou componentDidCatch ()
. Lequel (s) définissez-vous dépend de ce que vous voulez accomplir avec votre limite d'erreur.
Fonctions d'une limite d'erreur
Une limite d'erreur n'est pas un mur muet dont le seul but dans la vie est de garder un feu dans Les limites d'erreur font un travail réel. Pour commencer, ils attrapent des erreurs javascript. Ils peuvent également consigner ces erreurs et afficher une interface utilisateur de secours. Passons en revue chacune de ces fonctions l'une après l'autre.
Détection des erreurs JavaScript
Lorsqu'une erreur est lancée à l'intérieur d'un composant, la limite d'erreur est la première ligne de défense. Dans notre dernière illustration, si une erreur se produit lors du rendu du composant la limite d'erreur intercepte cette erreur et l'empêche de se propager vers l'extérieur.
Enregistre ces erreurs
Ceci est entièrement facultatif. Vous pouvez intercepter l'erreur sans l'enregistrer. C'est comme tu veux. Vous pouvez faire ce que vous voulez avec les erreurs levées. Enregistrez-les, enregistrez-les, envoyez-les quelque part, montrez-les à vos utilisateurs (vous ne voulez vraiment pas le faire). C'est à vous de décider.
Mais pour accéder aux erreurs, vous devez définir la méthode de cycle de vie componentDidCatch ()
.
Rendre une interface utilisateur de secours
Ceci, comme la journalisation des erreurs, est entièrement facultatif. Mais imaginez que vous aviez des invités importants et que l'alimentation devait être coupée. Je suis sûr que vous ne voulez pas que vos invités tâtonnent dans le noir, alors vous inventez une technologie pour allumer les bougies instantanément. Magique, hmm. Eh bien, vos utilisateurs sont des invités importants et vous voulez leur offrir la meilleure expérience dans toutes les situations.
Vous pouvez restituer une interface utilisateur de secours avec getDerivedStateFromError ()
statique après qu'une erreur a été levée.
Il est important de noter que les limites d'erreur ne détectent pas d'erreurs dans les situations suivantes:
- Erreurs dans l'événement
- Erreurs dans le code asynchrone (par exemple
setTimeout
ourappels requestAnimationFrame
). - Erreurs qui se produisent lorsque vous effectuez un rendu côté serveur.
- Erreurs sont jetés dans la limite d'erreur elle-même (plutôt que dans ses enfants). Cependant, une autre limite d'erreur pourrait intercepter cette erreur.
Utilisation des limites d'erreur
Passons maintenant à notre éditeur de code. Pour suivre, vous devez cloner le référentiel .
Après avoir cloné le dépôt, consultez la branche 01-initial-setup . Une fois cela fait, exécutez les commandes suivantes pour démarrer l'application.
# install project dependencies
installation de fil
# démarrer le serveur
Yarn start
Au démarrage, l'application affiche ce que nous avons dans l'image ci-dessous.

L'application a actuellement un en-tête et deux colonnes. En cliquant sur Obtenir des images dans la colonne de gauche, vous appelez l'API à l'URL https://picsum.photos/v2/list?page=0&limit=2
et affiche deux images. Dans la colonne de droite, nous avons quelques textes de description et deux boutons.
Lorsque nous cliquons sur le bouton Remplacer la chaîne par un objet
nous remplaçons le texte {"fonction": "Je vis pour planter "}
qui a été stratifié
avec l'objet JavaScript simple. Cela déclenchera une erreur car React ne restitue pas les objets JavaScript simples. Cela entraînera le blocage de la page entière et la rendra vierge. Nous devrons actualiser la page pour récupérer notre vue.
Essayez-la par vous-même.
Actualisez maintenant la page et cliquez sur le bouton Invoquer le gestionnaire d'événements
. Vous verrez une fenêtre contextuelle d'erreur, avec un petit X
dans le coin supérieur droit. Cliquer dessus supprime l'écran d'erreur et vous montre la page rendue, sans avoir besoin de rafraîchir. Dans ce cas, React sait toujours quoi afficher même si une erreur est levée dans le gestionnaire d'événements. Dans un environnement de production, cet écran d'erreur n'apparaîtra pas du tout et la page restera intacte. Vous ne pouvez voir que quelque chose s'est mal passé si vous regardez dans la console du développeur.

Remarque : Pour exécuter l'application en mode production, vous devez installer servir globalement. Après avoir installé le serveur, créez l'application et démarrez-la avec la commande ci-dessous.
# créez l'application pour la production
construction de fil
# servir l'application à partir du dossier de construction
serve -s build
Après avoir vu comment React gère deux types d'erreurs (erreur de rendu et erreur de gestionnaire d'événements), écrivons maintenant un composant de limite d'erreur.
Créez un nouveau ErrorBoundary.js
fichier à l'intérieur du dossier / src
et construisons le composant de limite d'erreur morceau par morceau.
import React, {Component} from 'react';
importer des PropTypes à partir de «prop-types»;
exporter la classe par défaut ErrorBoundary étend le composant {
état = {
Erreur: '',
errorInfo: '',
hasError: false,
};
getDerivedStateFromError statique (erreur) {
return {hasError: true, error};
}
componentDidCatch (error, errorInfo) {
// eslint-disable-next-line sans console
console.log ({error, errorInfo});
this.setState ({errorInfo});
}
render () {
// le bloc de code suivant va ici
}
}
ErrorBoundary.propTypes = {
enfants: PropTypes.oneOfType ([ PropTypes.object, PropTypes.array ]). isRequired,
};
Nous définissons les deux méthodes de cycle de vie qui font d'un composant une limite d'erreur. Chaque fois qu'une erreur se produit dans le composant enfant de la limite d'erreur, nos deux méthodes de cycle de vie sont activées.
-
static getDerivedStateFromError ()
reçoit l'erreur et met à jour les variables d'état,error
ethasError
. -
componentDidCatch ()
reçoit l'erreurerrorInfo
qui est un objet avec uncomponentStack
clé contenant des informations sur le composant qui a provoqué l'erreur. Ici, nous avons enregistré l'erreur et également mis à jour l'état avec leerrorInfo
. C'est à vous de décider ce que vous voulez faire avec ces deux-là.
Ensuite, dans la méthode de rendu, nous renvoyons this.props.children
qui représente le composant que contient cette limite d'erreur.
Ajoutons le dernier morceau de code. Copiez le code suivant et collez-le dans la méthode render ()
.
const {hasError, errorInfo} = this.state;
if (hasError) {
revenir (
Une erreur s'est produite lors du chargement de cette page. {''}
{
window.location.reload ();
}}
>
Recharger cette page
{''}
Cliquez pour des détails sur l'erreur
{errorInfo && errorInfo.componentStack.toString ()}
);
}
Dans la méthode render ()
nous vérifions si hasError
est vrai. Si c'est le cas, nous rendons la div
qui est notre interface utilisateur de secours. Ici, nous montrons des informations sur l'erreur et une option pour recharger la page. Cependant, dans un environnement de production, il n'est pas conseillé de montrer l'erreur à l'utilisateur. Un autre message conviendrait.
Utilisons maintenant notre composant ErrorBoundary
. Ouvrez App.js
importez ErrorBoundary
et affichez-y ColumnRight
.
# importez la limite d'erreur
import ErrorBoundary de './ErrorBoundary';
# envelopper la colonne de droite avec la limite d'erreur
Cliquez maintenant sur Remplacez la chaîne par l'objet
. Cette fois, la colonne de droite se bloque et l'interface utilisateur de secours s'affiche. Nous affichons un rapport détaillé indiquant où l'erreur s'est produite. Nous voyons également le journal des erreurs dans la console du développeur.

Nous pouvons voir que tout le reste reste en place. Cliquez sur Obtenir des images
pour confirmer que cela fonctionne toujours comme prévu.
À ce stade, je tiens à mentionner qu'avec les limites d'erreur, vous pouvez aller aussi granuleusement que vous le souhaitez. Cela signifie que vous pouvez en utiliser autant que nécessaire. Vous pouvez même avoir plusieurs limites d'erreur dans un seul composant.
Avec notre utilisation actuelle de Limite d'erreur
un clic sur Remplacer la chaîne par l'objet
bloque toute la colonne de droite. Voyons comment nous pouvons améliorer cela.
Ouvrez src / colonnes / ColumnRight.js
importez ErrorBoundary
et affichez le deuxième
bloc à l'intérieur. Il s'agit du paragraphe qui bloque le composant
.
# importer le composant
import ErrorBoundary de '../ErrorBoundary';
# rendre le paragraphe erroné à l'intérieur.
Cliquer sur ce bouton remplacera l'objet stratifié
{''}
{text}
avec l'objet d'origine. Cela se traduira par une
erreur de rendu.
Cliquez maintenant sur Remplacez la chaîne par l'objet
.

Cette fois, nous avons encore la majeure partie de la page intacte. Seul le deuxième paragraphe est remplacé par notre interface utilisateur de secours.
Cliquez pour vous assurer que tout le reste fonctionne.
Si vous souhaitez consulter mon code à ce stade, vous devriez consulter le 02- create-eb branch.
Dans le cas où vous vous demandez si tout ce truc de limite d'erreur est cool, laissez-moi vous montrer ce que j'ai capturé sur Github il y a quelques jours. Regardez le contour rouge.

Je ne suis pas certain de ce qui se passe ici, mais cela ressemble à une limite d'erreur.
Les limites d'erreur sont cool, mais nous ne voulons pas d'erreurs dans le première place. Nous devons donc surveiller les erreurs à mesure qu'elles se produisent afin que nous puissions avoir une meilleure idée de la façon de les corriger. Dans cette section, nous apprendrons comment Sentry peut nous aider à cet égard.
Intégration avec Sentry
Lorsque j'ai ouvert la page d'accueil de Sentry en écrivant cette ligne, j'ai été accueilli par ce message.
Les erreurs logicielles sont inévitables. Le chaos ne l'est pas.
Sentry fournit une surveillance des erreurs auto-hébergée et basée sur le cloud qui aide toutes les équipes logicielles à découvrir, trier et hiérarchiser les erreurs en temps réel.
Sentry est un service commercial de rapport d'erreurs. Il existe de nombreuses autres sociétés qui fournissent des services similaires. Mon choix de Sentry pour cet article est parce qu'il a un plan de développement gratuit qui me permet de me connecter jusqu'à 5 000 événements par mois sur tous mes projets ( documents de tarification ). Un événement est un rapport de plantage (également appelé exception ou erreur). Pour ce didacticiel, nous utiliserons le plan de développement gratuit.
Vous pouvez intégrer Sentry à de nombreux frameworks Web. Passons en revue les étapes pour l'intégrer dans notre projet React.
- Visitez le site Web Sentry et créez un compte ou connectez-vous si vous en avez déjà un.
- Cliquez sur
Projets
dans la navigation de gauche. Cliquez ensuite surCréer un projet
pour démarrer un nouveau projet. - Sous
Choisissez une plate-forme
sélectionnez Réagir. - Sous
Définissez vos paramètres d'alerte par défaut
checkAlertez-moi de chaque nouveau numéro
. - Donnez un nom à votre projet et cliquez sur
Créer un projet
. Cela créera le projet et vous redirigera vers la page de configuration.
Installez le SDK du navigateur Sentry.
# installez Sentry
yarn add @ sentry / browser
Sur la page de configuration, copiez le code d'initialisation du SDK du navigateur et collez-le dans votre fichier index.js
.
importez * en tant que Sentry depuis '@ Sentry / browser' ;
# Initialiser avec le nom de la source de données (dsn)
Sentry.init ({dsn: 'dsn-string'});
Et cela suffit pour que Sentry commence à envoyer des alertes d'erreur. Il est dit dans les documents
Remarque : Seul, @ Sentry / browser
signalera toutes les exceptions non détectées déclenchées à partir de votre application.
Cliquez sur Je l'ai! Accédez au flux de problèmes
pour accéder au tableau de bord des problèmes. Maintenant, revenez à votre application dans le navigateur et cliquez sur les boutons rouges pour lancer une erreur. Vous devriez recevoir des alertes par e-mail pour chaque erreur (parfois les e-mails sont retardés). Actualisez votre tableau de bord des problèmes pour voir les erreurs.

Le tableau de bord Sentry fournit de nombreuses informations sur l'erreur qu'il reçoit. Vous pouvez voir des informations telles qu'un graphique de la fréquence d'occurrence de chaque type d'événement d'erreur. Vous pouvez également affecter chaque erreur à un membre de l'équipe. Il y a une tonne d'informations. Prenez le temps de les explorer pour voir ce qui vous est utile.
Vous pouvez cliquer sur chaque problème pour voir des informations plus détaillées sur l'événement d'erreur.
Utilisons maintenant Sentry pour signaler les erreurs détectées par notre erreur. frontière. Ouvrez ErrorBoundary.js
et mettez à jour les éléments de code suivants.
# import Sentry
importer * en tant que sentinelle à partir de '@ sentinelle / navigateur'
# ajouter eventId à l'état
état = {
Erreur: '',
eventId: '', // ajoute ceci à l'état
errorInfo: '',
hasError: false,
};
# update componentDidCatch
componentDidCatch (error, errorInfo) {
// eslint-disable-next-line sans console
console.log ({error, errorInfo});
Sentry.withScope ((scope) => {
scope.setExtras (errorInfo);
const eventId = Sentry.captureException (erreur);
this.setState ({eventId, errorInfo});
});
}
Avec cette configuration, Sentry envoie toutes les erreurs capturées par notre limite d'erreur à notre tableau de bord de problème à l'aide de la méthode Sentry.captureException
.
Sentry nous fournit également un outil pour recueillir les commentaires des utilisateurs. Ajoutons le bouton de rétroaction dans le cadre de notre interface de secours à l'intérieur de notre limite d'erreur.
Ouvrez ErrorBoundary.js
et ajoutez le bouton de rétroaction juste après la division
avec un nom de classe de ] corps de carte
. Vous pouvez placer ce bouton où bon vous semble.
...
# ajoutez le bouton Sentry
Maintenant, chaque fois que notre interface de secours est rendue, le bouton Rapport de rétroaction
s'affiche. Un clic sur ce bouton ouvre une boîte de dialogue que l'utilisateur peut remplir pour nous fournir des commentaires.

Allez-y et déclenchez une erreur, puis remplissez et soumettez le formulaire de commentaires. Accédez maintenant à votre tableau de bord Sentry et cliquez sur Commentaires des utilisateurs
dans la navigation de gauche. Vous devriez voir vos commentaires signalés.

Actuellement, nous recevons des alertes pour chaque erreur, même celles qui se produisent pendant le développement. Cela tend à obstruer notre flux de problèmes. Signalons uniquement les erreurs qui se produisent en production.
Dans la navigation de gauche, cliquez sur Paramètres
. Sous le menu ORGANISATION
cliquez sur Projets
. Dans cette liste, cliquez sur votre projet de limite d'erreur. Dans Paramètres du projet
sur le côté gauche, cliquez sur Filtres entrants
. Recherchez Filtrez les événements provenant de localhost
et activez-le. Ce n'est là qu'une des nombreuses configurations disponibles dans Sentry. Je vous encourage à jeter un coup d'œil pour voir ce qui pourrait être utile pour votre projet.
Si vous souhaitez jeter un œil à mon code, la branche correspondante dans mon référentiel est 03-integr -sentry .
Conclusion
Si vous n'avez pas utilisé de limites d'erreur dans votre application React, vous devez immédiatement en ajouter une au niveau supérieur de votre application. Aussi, je vous encourage à intégrer un service de rapport d'erreurs dans votre projet. Nous avons vu à quel point il est facile de démarrer gratuitement avec Sentry.
La version finale de l'application est hébergée sur Netlify .
Ressources connexes
![Smashing Editorial [19659151] (ks, ra, yk, il) </span></div>
</div>
<p><div class=](https://i0.wp.com/blog.arcoptimizer.com/wp-content/uploads/2018/04/1523030185_12_frappez-le-terrain-en-courant-avec-vue-js-et-firestore-smashing-magazine.png?w=660)
Source link