J'essaye d'étendre l'erreur avec ES6 et Babel. Ça ne marche pas.
class MyError extends Error {
constructor(m) {
super(m);
}
}
var error = new Error("ll");
var myerror = new MyError("ll");
console.log(error.message) //shows up correctly
console.log(myerror.message) //shows empty string
L'objet Error n'obtient jamais le bon ensemble de messages.
Maintenant, j'ai vu quelques solutions sur SO ( par exemple ici ), mais elles semblent toutes très peu ES6-y. Comment le faire d'une manière agréable ES6? (Cela fonctionne à Babel)
javascript
ecmascript-6
babeljs
transpiler
Karel Bílek
la source
la source
Réponses:
Sur la base de la réponse de Karel Bílek, j'apporterais un petit changement au
constructor
:Cela s'imprimera
MyError
dans la pile, et non dans le génériqueError
.Il ajoutera également le message d'erreur à la trace de la pile - qui manquait dans l'exemple de Karel.
Il utilisera également
captureStackTrace
s'il est disponible.Avec Babel 6, vous avez besoin de transform-builtin-extend ( npm ) pour que cela fonctionne.
la source
if (typeof Error.captureStackTrace === 'function') { Error.captureStackTrace(this, this.constructor.name) } else { this.stack = (new Error(message)).stack; }
. Je dirais qu'il est préférable d'utiliser cette fonction si elle est disponible, car elle fournit une pile d'appels plus `` native '' et imprime le nom de l'objet d'erreur. Bien sûr, si vous l'utilisez uniquement du côté serveur (Node), ce n'est pas non plus un problème.this.stack = (new Error(message)).stack
vous obtient systématiquement cela ... mais en pratique, ce n'est probablement pas un gros problème.new MyError('foo') instanceof MyError === false
extendable-error-class
npmjs.com/package/extendable-error-class, ce qui est pratique pour éviter une dépendance sur babel-plugin-transform-builtin-extendthis.message = message;
est redondant avecsuper(message);
En combinant cette réponse , cette réponse et ce code , j'ai créé cette petite classe "helper", qui semble bien fonctionner.
Essayez en REPL
la source
this.stack = (new Error(message)).stack;
- sinon le message est absent du stacktracemessage
dans le constructeur de pile d'erreur, de sorte qu'il affiche le bon message en haut de la pile lorsqu'il est lancé:this.stack = (new Error(message)).stack;
myerror.name
renvoie maintenant "Erreur". Je ne sais pas si cela est lié aux versions ultérieures de babel.Voir la réponse de @ sukima ciPour enfin mettre cela au repos. Dans Babel 6 , il est explicite que les développeurs ne prennent pas en charge allant de construction. Bien que cette astuce ne aide avec des choses comme
Map
,Set
, etc. , il travaille pourError
. Ceci est important car l'une des idées fondamentales d'un langage qui peut lever une exception est d'autoriser les erreurs personnalisées. Ceci est doublement important car les promesses deviennent plus utiles puisqu'elles sont conçues pour rejeter une erreur .La triste vérité est que vous devez toujours effectuer cela à l'ancienne dans ES2015.
Exemple dans Babel REPL
Modèle d'erreur personnalisé
D'un autre côté, il existe un plugin pour Babel 6 pour permettre cela.
https://www.npmjs.com/package/babel-plugin-transform-builtin-extend
Mise à jour: (à partir du 29/09/2016) Après quelques tests, il semble que babel.io ne tient pas correctement compte de toutes les assertions (à partir d'une erreur étendue personnalisée). Mais dans Ember.JS, l'extension Error fonctionne comme prévu: https://ember-twiddle.com/d88555a6f408174df0a4c8e0fd6b27ce
la source
Error.toString()
. La nécessité de faire des cercles et des girations spéciaux pour accomplir cela signifie que la plupart des développeurs l'éviteront et auront recours à de mauvaises pratiques comme lancer des cordes au lieu d'erreurs. Ou créer leur propre carte comme des objets. Pourquoi la nécessité de dissuader de telles méthodes POO?Edit : changements de rupture dans Typescript 2.1
La modification de la réponse originale de Lee Benson fonctionne un peu pour moi. Cela ajoute également
stack
des méthodes deExtendableError
classe supplémentaires à l'instance.la source
Object.setPrototypeOf
leMyError
constructeur. stackoverflow.com/a/41102306/186334 github.com/Microsoft/TypeScript-wiki/blob/master/…Avec les dernières modifications apportées à babel 6, je trouve que l' extension intégrée de la transformation ne fonctionne plus. J'ai fini par utiliser cette approche mixte:
et
En conséquence, tous ces tests réussissent:
la source
Citer
Bien que les codes ci-dessus ne puissent pas générer la trace de la pile, sauf si
this.stack = (new Error()).stack;
ouError.captureStackTrace(this, this.constructor.name);
est appelé dans Babel . OMI, c'est peut-être un problème ici.En fait, la trace de la pile peut être sortie sous
Chrome console
etNode.js v4.2.1
avec ces extraits de code.Sortie de
Chrome console
.Sortie de
Node.js
la source
En plus de la réponse @zangw, vous pouvez définir vos erreurs comme ceci:
qui lancera le nom, le message et la trace de pile corrects:
la source
new MyError('foo') instanceof MyError === false
.Node.js v7.7.3
.Cette
class MyError extends Error {…}
syntaxe est correcte.Notez que les transpileurs ont encore des problèmes avec l'héritage des objets intégrés. Dans ton cas,
semble résoudre le problème.
la source
Error.call()
renvoie une nouvelle instance d'erreur pour moi.Compte tenu de cela, la réponse acceptée ne fonctionne plus, vous pouvez toujours utiliser une usine comme alternative ( repl ):
la source
Je préfère une syntaxe plus forte que celle décrite ci-dessus. Des méthodes supplémentaires au type d'erreur vous aideront à créer joli
console.log
ou autre chose.Pour tester ce code, vous pouvez exécuter quelque chose de similaire:
Les extensions de
CustomError
type sont les bienvenues. Il est possible d'ajouter des fonctionnalités spécifiques au type étendu ou de remplacer l'existant. Par exemple.la source
Comme le mentionne @sukima, vous ne pouvez pas étendre le JS natif. Il est impossible de répondre à la question du PO.
Semblable à la réponse de Melbourne2991 , j'ai plutôt utilisé une usine, mais j'ai suivi la recommandation de MDN pour les types d'erreur des clients .
la source
Cela fonctionne pour moi:
la source
Je n'utilise pas Babel, mais dans ES6 simple, ce qui suit semble fonctionner correctement pour moi:
Test de REPL:
Comme vous pouvez le voir, la pile contient à la fois le nom et le message d'erreur. Je ne sais pas si je manque quelque chose, mais toutes les autres réponses semblent trop compliquer les choses.
la source
J'ai amélioré un peu la solution de @Lee Benson de cette façon:
extendableError.js
un exemple d'erreur
Ensuite, vous êtes en mesure de regrouper les erreurs tout en ayant des spécificateurs d'options pour décider quoi faire différemment dans certaines situations spécifiques à votre application
la source