Pour une raison quelconque, il semble que la délégation de constructeur ne fonctionne pas dans l'extrait de code suivant:
function NotImplementedError() {
Error.apply(this, arguments);
}
NotImplementedError.prototype = new Error();
var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")
L'exécution de cela donne The message is: ''
. Avez-vous des idées sur la raison ou s'il existe un meilleur moyen de créer une nouvelle Error
sous-classe? Y a-t-il un problème avec apply
le Error
constructeur natif que je ne connais pas?
javascript
exception
cdleary
la source
la source
Réponses:
Mettez à jour votre code pour affecter votre prototype au prototype Error.prototype et l'instanceof et vos assertions fonctionnent.
Cependant, je voudrais simplement jeter votre propre objet et vérifier la propriété name.
Modifier en fonction des commentaires
Après avoir regardé les commentaires et essayé de me rappeler pourquoi j'attribuerais un prototype à la
Error.prototype
place denew Error()
Nicholas Zakas dans son article , j'ai créé un jsFiddle avec le code ci-dessous:La sortie de la console était la suivante.
Cela confirme que le "problème" que j'ai rencontré était la propriété de pile de l'erreur était le numéro de ligne où a
new Error()
été créé, et non oùthrow e
s'est produit. Cependant, cela peut être mieux que d'avoir l'effet secondaire d'uneNotImplementedError.prototype.name = "NotImplementedError"
ligne affectant l'objet Error.Aussi, notez avec
NotImplementedError2
, quand je ne définis pas.name
explicitement, c'est égal à "Erreur". Cependant, comme mentionné dans les commentaires, car cette version définit le prototype surnew Error()
, je pourrais définirNotImplementedError2.prototype.name = "NotImplementedError2"
et être OK.la source
Error.prototype
directement est probablement une mauvaise forme. Si vous souhaitez ajouter plus tard unNotImplementedError.prototype.toString
alias d'objet, ilError.prototype.toString
vaut mieux faireNotImplementedError.prototype = new Error()
.subclass.prototype = new Error()
est une mauvaise forme. Vous êtes censé utiliser à lasubclass.prototype = Object.create(superclass.prototype)
place. J'espère que cela pourrait également résoudre le problème de trace de pile.this.stack = new Error().stack;
NotImplementedError.prototype = Error.prototype;
ne fait pas deinstanceof
traiterNotImplementedError
une sous - classe deError
, il les faitinstanceof
traiter exactement comme la même classe. Si vous collez le code ci-dessus dans votre console et essayez,new Error() instanceof NotImplementedError
vous obtiendreztrue
, ce qui est clairement faux.Toutes les réponses ci-dessus sont terriblement horribles - vraiment. Même celui avec 107 ups! La vraie réponse est ici les gars:
Héritage de l'objet Error - où se trouve la propriété de message?
TL; DR:
R. La raison
message
n'est pas défini est queError
est une fonction qui retourne un nouvel objet d'erreur et ne pas manipulerthis
d'aucune façon.B. La façon de faire ce droit est de renvoyer le résultat de la demande du constructeur, ainsi que de définir le prototype de la manière habituelle javascript compliquée:
Vous pourriez probablement faire une supercherie pour énumérer toutes les propriétés non énumérables de l'
tmp
erreur pour les définir plutôt que de définir explicitement uniquementstack
etmessage
, mais la supercherie n'est pas prise en charge dans ie <9la source
return this
dans un constructeur.temp.name = this.name = 'MyError'
, vous pouvez le fairetemp.name = this.name = this.constructor.name
. De cette façon, cela fonctionnera également pour les sous-classes deMyError
.Dans ES2015, vous pouvez utiliser
class
pour le faire proprement:Cela ne modifie pas le global
Error
prototype, vous permet de personnalisermessage
,name
et d' autres attributs, et capture correctement la pile. C'est aussi assez lisible.Bien sûr, vous devrez peut-être utiliser un outil comme
babel
si votre code s'exécutera sur des navigateurs plus anciens.la source
Si quelqu'un est curieux de savoir comment créer une erreur personnalisée et obtenir la trace de la pile:
la source
Cette section de la norme peut expliquer pourquoi l'
Error.apply
appel n'initialise pas l'objet:Dans ce cas, la
Error
fonction détermine probablement qu'elle n'est pas appelée en tant que constructeur, elle renvoie donc une nouvelle instance d'erreur plutôt que d'initialiser l'this
objet.Les tests avec le code suivant semblent démontrer que c'est en fait ce qui se passe:
La sortie suivante est générée lors de son exécution:
la source
this
inError.apply(this, arguments);
? Je dis que l'appel à Error ici construit un nouvel objet, qui est jeté; ne pas initialiser l'objet déjà construit auquel est affecténie
.NotImplementedError
implémentation ne devrait-elle pas retourner lareturned
variable?la source
J'ai eu un problème similaire à celui-ci. Mon erreur doit être à la
instanceof
foisError
etNotImplemented
, et elle doit également produire une trace cohérente dans la console.Ma solution:
Résultat de l'exécution avec node.js:
L'erreur passe tous les 3 de mes critères, et bien que la
stack
propriété ne soit pas standard, elle est prise en charge dans la plupart des navigateurs les plus récents, ce qui est acceptable dans mon cas.la source
En accédant à Joyent, vous ne devriez pas jouer avec la propriété stack (que je vois dans de nombreuses réponses données ici), car cela aura un impact négatif sur les performances. Voici ce qu'ils disent:
J'aime et j'aimerais mentionner leur idée d'envelopper l'erreur d'origine qui est un bon remplacement pour passer sur la pile.
Voici donc comment créer une erreur personnalisée, compte tenu de ce qui précède:
version es5:
version es6:
J'ai mis ma solution dans un module, la voici: https://www.npmjs.com/package/rerror
la source
J'aime le faire comme ça:
"{code}: {message}"
error.code
car la vérification / l'analyse d'un code est meilleure dans le code que la vérification d'un message, que vous voudrez peut-être localiser par exempleerror.message
comme alternative àerror.toString()
la source
J'ai juste dû implémenter quelque chose comme ça et j'ai constaté que la pile était perdue dans ma propre implémentation d'erreur. Ce que je devais faire était de créer une erreur factice et de récupérer la pile à partir de cela:
la source
J'ai utilisé le modèle de constructeur pour créer le nouvel objet d'erreur. J'ai défini la chaîne de prototype telle qu'une
Error
instance. Voir la référence du constructeur MDN Error .Vous pouvez vérifier cet extrait sur cet essentiel .
LA MISE EN OEUVRE
USAGE
Le constructeur CustomError peut recevoir de nombreux arguments pour générer le message, par exemple
Et voici à quoi ressemble l'erreur personnalisée:
la source
Le constructeur doit être comme une méthode d'usine et retourner ce que vous voulez. Si vous avez besoin de méthodes / propriétés supplémentaires, vous pouvez les ajouter à l'objet avant de le renvoyer.
Mais je ne sais pas pourquoi vous auriez besoin de faire ça. Pourquoi ne pas simplement utiliser
new Error...
? Les exceptions personnalisées n'ajoutent pas grand-chose en JavaScript (ou probablement dans n'importe quel langage non typé).la source
Ceci est bien implémenté dans Cesium DeveloperError:
Sous sa forme simplifiée:
la source
error instanceof Error
test, ce qui peut être utile.Voici ma mise en œuvre:
Exemple d'utilisation # 1:
Exemple d'utilisation # 2:
la source
Au détriment de ne pas pouvoir utiliser
instanceof
, ce qui suit préserve la trace de pile d'origine et n'utilise aucune astuce non standard.la source
fixError
fonction ci-dessus. L'ajout d'unnew
lors de son appel ne ferait que créer un objet qui serait jeté.Une autre alternative, pourrait ne pas fonctionner dans tous les environnements.Au moins assuré que cela fonctionne dans nodejs 0.8 Cette approche utilise un moyen non standard de modifier le prop prop interne
la source
Si vous utilisez Node / Chrome. L'extrait suivant vous fournira une extension qui répond aux exigences suivantes.
err instanceof Error
err instanceof CustomErrorType
[CustomErrorType]
lorsqu'il est créé avec un message[CustomErrorType: message]
lorsqu'il est créé sans messageif
instructions et vous êtes prêt à partir .Fragment
Usage
Production
la source
Ce qui suit a fonctionné pour moi tiré de la documentation officielle de Mozilla Erreur .
la source
Essayez un nouvel objet prototype pour chaque instance du type d'erreur défini par l'utilisateur. Il permet aux
instanceof
contrôles de se comporter comme d'habitude et le type et le message sont correctement signalés dans Firefox et V8 (Chome, nodejs).Notez qu'une entrée supplémentaire précède la pile sinon correcte.
la source
var a = new NotImplementedError('a'), b = new NotImplementedError('b');
. Maintenanta instanceof NotImplementedError == false
etb instanceof NotImplementedError == true
C'est le moyen le plus rapide de le faire:
la source
moyen plus facile. Vous pouvez faire hériter votre objet de l'objet Error. Exemple:
ce que nous faisons est d'utiliser la fonction call () qui appelle le constructeur de la classe Error, c'est donc fondamentalement la même chose que d'implémenter un héritage de classe dans d'autres langages orientés objet.
la source
MDN a un excellent exemple :
la source