Gestion des erreurs dans Vue


Toute l'année dernière, j'ai travaillé avec mon framework préféré, Vue.js, pour le décrire et le représenter. Et j'ai réalisé que je n'avais pas encore compris la gestion des erreurs dans Vue. Je voudrais expliquer cela en disant que j'écris du code parfait, mais nous savons tous comment les choses sont vraiment. Au cours des derniers jours, j'ai expérimenté les différentes méthodes de gestion des erreurs fournies par Vue et j'ai décidé de partager mes découvertes. Évidemment, cette revue ne couvrira pas tous les scénarios possibles, mais j'espère qu'elle vous aidera!

Erreurs


Pour tester différentes méthodes de traitement, j'ai décidé de prendre trois types d'erreurs différents (au moins pour commencer). Dans le premier cas, c'était juste un appel à une variable inexistante:

<div id="app" v-cloak> Hello, {{name}} </div> 

Dans cet exemple, l'utilisateur ne reçoit pas de message d'erreur, mais un avertissement [Vue warn] s'affiche dans la console.



Voici à quoi ressemble l'exécution de cet exemple:


Dans le deuxième exemple, j'ai essayé de lier une variable à une propriété calculée qui devrait générer une erreur:

 <div id="app" v-cloak> Hello, {{name2}} </div> 

 const app = new Vue({ el:'#app', computed:{ name2() { return x; } } }) 

Dans ce cas, l'avertissement [Vue warn] et le message d'erreur habituel sont affichés dans la console, mais rien n'est émis à l'utilisateur.



Voici comment s'exécute le code de cet exemple:


Dans le troisième exemple, j'ai utilisé une méthode qui devrait générer une erreur.

 <div id="app" v-cloak> <button @click="doIt">Do It</button> </div> 

 const app = new Vue({ el:'#app', methods:{ doIt() { return x; } } }) 

Comme dans le cas précédent, un message sur cette erreur dans la console sera affiché deux fois: un avertissement et un message sur cette erreur. Mais, contrairement à lui, une erreur ne se produit que lorsque le bouton est réellement enfoncé.



Et voici une démo pour cet exemple:


Avant de continuer, je tiens à préciser que ces exemples ne montrent pas tous les types d'erreurs que vous pouvez faire. Ce ne sont que quelques-uns des principaux, qui, à mon avis, peuvent souvent être trouvés dans des applications basées sur Vue.js.

Alors, comment pouvez-vous gérer les erreurs dans les applications Vue? Je dois dire que j'ai été un peu surpris que dans le guide principal du framework Vue il n'y ait pas de section sur la gestion des erreurs.



Oui, il y a une section similaire dans le manuel, mais elle est très courte, et toute sa signification correspond à la citation suivante:

«Si une erreur d'exécution se produit pendant le rendu du composant, elle sera transmise à la fonction de configuration globale Vue.config.errorHandler, si une a été spécifiée. Il serait probablement utile d'utiliser ce crochet en conjonction avec un service de suivi des bogues tel que Sentry, d'autant plus que son intégration avec Vue est officiellement prise en charge. »

À mon avis, ce sujet devrait être couvert un peu plus dans la documentation (et je pense que cela pourrait aider à le compléter). En général, la gestion des erreurs dans Vue se résume aux moyens suivants:

  • errorHandler;
  • warnHandler;
  • renderError;
  • errorCaptured;
  • window.onerror (cet outil n'est pas spécifique à Vue).

Examinons de plus près ces astuces.

Gestionnaire d'erreurs numéro un: errorHandler


Le premier remède est errorHandler . Comme vous l'avez probablement deviné, il s'agit du gestionnaire d'erreurs standard pour les applications Vue.js. Vous pouvez l'affecter comme suit:

 Vue.config.errorHandler = function(err, vm, info) { } 

Dans la déclaration de fonction ci-dessus, err est la description de l'erreur actuelle, info est la chaîne d'informations d'erreur spécifique à Vue et vm est l'application Vue actuelle. N'oubliez pas que plusieurs applications Vue peuvent s'exécuter sur la même page Web en même temps. Ce gestionnaire d'erreurs s'appliquera à tous. Prenons l'exemple simple suivant:

 Vue.config.errorHandler = function(err, vm, info) { console.log(`Error: ${err.toString()}\nInfo: ${info}`); } 

Dans le cas de la première erreur, ce code n'effectue aucune action. Si vous vous en souvenez, cela génère un avertissement , pas un message d'erreur.

Dans le second cas, l'erreur est traitée et le texte suivant s'affiche:

 Error: ReferenceError: x is not defined Info: render 

Enfin, le troisième exemple donne le résultat suivant:

 Error: ReferenceError: x is not defined Info: v-on handler 

Remarquez à quel point les informations sont «utiles» sous le titre Info dans les deux exemples précédents. Voyons maintenant comment l'outil suivant fonctionne.

Gestionnaire d'erreurs numéro deux: warnHandler


warnHandler gère - qu'en pensez-vous? - Avertissements de vue. Notez qu'en production, ce gestionnaire est ignoré. Le gestionnaire de cette méthode est également légèrement différent du précédent:

 Vue.config.warnHandler = function(msg, vm, trace) { } 

Les deux premiers arguments - msg et vm - ne nécessitent aucune explication supplémentaire et l'argument trace doit être une arborescence de composants. Prenons un exemple:

 Vue.config.warnHandler = function(msg, vm, trace) { console.log(`Warn: ${msg}\nTrace: ${trace}`); } 

Le premier exemple a maintenant un gestionnaire pour l'avertissement qu'il génère, et il renvoie ce qui suit:



Les deuxième et troisième exemples ne sont pas modifiés. Des exemples en direct pour les trois cas sont présentés ci-dessous.




Gestionnaire d'erreur numéro trois: renderError


Je vais maintenant montrer une troisième méthode de gestion des erreurs: renderError. Contrairement aux deux précédents, cet outil dépend du composant et n'est pas universel. Comme avec warnHandler, ce gestionnaire de production est désactivé.

Pour l'utiliser, insérez-le dans votre composant / application. Voici un exemple modifié de la documentation.

 const app = new Vue({ el:'#app', renderError (h, err) { return h('pre', { style: { color: 'red' }}, err.stack) } }) 

Si ce gestionnaire d'erreurs est utilisé dans le premier exemple, il ne fait rien, ce qui, si vous y réfléchissez, semble être logique, car le premier exemple donne un avertissement, pas une erreur. Si vous cochez ce gestionnaire dans le deuxième exemple, où la propriété calculée donne une erreur, vous verrez que son résultat est affiché à l'écran. Vous pouvez le voir dans la démonstration de codePen ci-dessous.


Honnêtement, je ne comprends pas très bien pourquoi utiliser cet outil lorsque la console est beaucoup plus pratique, mais si le service de contrôle de la qualité ou d'autres testeurs ne connaissent pas la console du navigateur, un message d'erreur plus simple à l'écran peut les aider.

Gestionnaire d'erreur numéro quatre: errorCaptured


Enfin, il y a l'outil errorCaptured (spécifique à Vue) qui m'a dérouté et, franchement, est toujours un peu déroutant. La documentation indique ce qui suit:

«Appelé si une erreur est commise dans un composant enfant. Ce hook reçoit trois arguments: une erreur, une instance du composant qui a provoqué l'erreur et une chaîne contenant des informations sur l'endroit où l'erreur a été enregistrée. Le crochet peut renvoyer false pour empêcher la propagation de l'erreur. "

Selon mes recherches (encore une fois, j'en doute fortement), ce gestionnaire d'erreur ne devrait être utilisé que par le composant parent qui gère l'erreur du composant enfant. Pour autant que je sache, il ne peut pas être utilisé dans l'instance principale de Vue, mais ne peut être utilisé que dans un composant qui a des enfants.

Pour vérifier cela, j'ai créé cet ensemble de composants parents et enfants:

 Vue.component('cat', { template:` <div><h1>Cat: </h1> <slot></slot> </div>`, props:{ name:{ required:true, type:String } }, errorCaptured(err,vm,info) { console.log(`cat EC: ${err.toString()}\ninfo: ${info}`); return false; } }); Vue.component('kitten', { template:'<div><h1>Kitten: {{ dontexist() }}</h1></div>', props:{ name:{ required:true, type:String } } }); 

Notez que le composant chaton contient une erreur. Maintenant, si j'essaie d'utiliser ce composant comme suit,

 <div id="app" v-cloak> <cat name="my cat"> <kitten></kitten> </cat> </div> 

Je vais recevoir un message du gestionnaire:

 cat EC: TypeError: dontexist is not a function info: render 

Vous pouvez le voir dans l'exemple ci-dessous.


Alors oui, un outil intéressant. Je crois qu'il sera principalement utilisé par ceux qui créent des bibliothèques de composants avec des relations parent / enfant. Cet outil est plus adapté au développeur de bibliothèque qu'au développeur ordinaire, si une telle division est logique. Mais encore une fois, ce n'est que ma première impression de cet outil.

Un seul outil pour tout gérer dans le monde: window.onerror



La dernière option (et la plus puissante) consiste à utiliser window.onerror , un gestionnaire d'erreur global pour tout ce qui peut se produire lorsque votre code JavaScript est exécuté. Ce gestionnaire a le format suivant:

 window.onerror = function(message, source, line, column, error) { } 

La seule chose que vous ne pouvez pas deviner dans le code ci-dessus est probablement la signification de l'argument source, qui est l'URL du script.

C'est là que le plaisir commence. Si vous définissez cette fonction, mais n'utilisez pas Vue.config.errorHandler, cela ne vous aidera pas. Vue s'attend à ce que vous définissiez Vue.config.errorHandler, et si vous ne le faites pas, il ne propagera pas l'erreur au-delà de ses limites. Probablement, cela a un certain sens ... Je ne sais même pas, pour moi, cela n'a pas beaucoup de sens. Une chose encore plus étrange: disons qu'il y a une erreur dans votre gestionnaire d'erreurs Vue lui-même. Il n'atteint pas non plus le gestionnaire window.onerror.

Voici une démo sur CodePen avec un exemple correspondant. J'ai commenté l'erreur dans errorHandler, mais si vous supprimez le commentaire, vous verrez que le gestionnaire d'erreur global ne fonctionnera pas. Cela ne fonctionnera que dans un cas: si vous appuyez sur le deuxième bouton.


Conclusion


J'espère que le contenu de cet article sera utile aux lecteurs. Comme déjà écrit au tout début, je viens de commencer à traiter ce sujet, donc, bien sûr, j'attends des commentaires, des commentaires et des suggestions. Je suis heureux de lire comment d’autres développeurs utilisent ces outils dans leurs applications!

Photo au début de l'article: auteur - David Kovalenko , site Unsplash

Source: https://habr.com/ru/post/fr460539/


All Articles