Quelle est la différence entre `throw new Error` et` throw someObject`?

378

Je veux écrire un gestionnaire d'erreurs commun qui capturera volontairement les erreurs personnalisées sur n'importe quelle instance du code.

Quand j'ai throw new Error('sample')aimé dans le code suivant

try {
    throw new Error({'hehe':'haha'});
    // throw new Error('hehe');
} catch(e) {
    alert(e);
    console.log(e);
}

Le journal s'affiche dans Firefox as Error: [object Object]et je n'ai pas pu analyser l'objet.

Pour la seconde, throwle journal affiche:Error: hehe

Alors que quand je l'ai fait

try {
    throw ({'hehe':'haha'});
} catch(e) {
    alert(e);
    console.log(e);
}

la console s'est affichée comme: Object { hehe="haha"}dans laquelle j'ai pu accéder aux propriétés d'erreur.

Quelle est la différence?

La différence est-elle visible dans le code? Une chaîne similaire sera simplement passée en tant que chaîne et un objet en tant qu'objets, mais la syntaxe sera-t-elle différente?

Je n'ai pas exploré lancer un objet d'erreur… Je n'avais fait que lancer des cordes.

Existe-t-il un autre moyen que les deux méthodes mentionnées ci-dessus?

Jayapal Chandran
la source
6
Le problème avec throw new Error ({prop: val}) est que ce n'est pas une construction valide de Error. L'erreur a des propriétés connues telles que discutées par Hemant.
grantwparks

Réponses:

216

Voici une bonne explication sur l' objet Error et le lancement de vos propres erreurs

L'objet d'erreur

Que pouvons-nous en extraire en cas d'erreur? L'objet Error dans tous les navigateurs prend en charge les deux propriétés suivantes:

  • name: le nom de l'erreur, ou plus précisément, le nom de la fonction constructeur à laquelle appartient l'erreur.

  • message: une description de l'erreur, cette description variant en fonction du navigateur.

Six valeurs possibles peuvent être renvoyées par la propriété name, qui, comme mentionné, correspond aux noms des constructeurs de l'erreur. Elles sont:

Error Name          Description

EvalError           An error in the eval() function has occurred.

RangeError          Out of range number value has occurred.

ReferenceError      An illegal reference has occurred.

SyntaxError         A syntax error within code inside the eval() function has occurred.
                    All other syntax errors are not caught by try/catch/finally, and will
                    trigger the default browser error message associated with the error. 
                    To catch actual syntax errors, you may use the onerror event.

TypeError           An error in the expected variable type has occurred.

URIError            An error when encoding or decoding the URI has occurred 
                   (ie: when calling encodeURI()).

Lancer vos propres erreurs (exceptions)

Au lieu d'attendre que l'un des 6 types d'erreurs se produise avant que le contrôle ne soit automatiquement transféré du bloc try au bloc catch, vous pouvez également lever explicitement vos propres exceptions pour forcer cela à se produire à la demande. C'est idéal pour créer vos propres définitions de ce qu'est une erreur et quand le contrôle doit être transféré à catch.

Hemant Metalia
la source
4
Oh oui. c'est une bonne chose que j'ai ratée avant de poser cette question. de toute façon, les utilisateurs recherchant des informations à ce sujet seront effacés. Maintenant, je suis clair sur ce qui est quoi. :) Merci. je serai de retour pour voter dans quelques jours.
Jayapal Chandran
185
Ne répond même pas encore à la question la réponse la plus votée?
user9993
@ user9993 L'utilisateur a posé la question à la recherche d'une compréhension détaillée selon le chat à ce moment-là, donc la réponse a été fournie et utile à l'utilisateur. c'est la raison pour laquelle les votes ont été acceptés et les plus élevés.
Hemant Metalia
5
@HemantMetalia Mais il a raison, la réponse ne montre même pas la moindre tentative de répondre à la question des PO comme indiqué. Si une réponse très différente dans le chat a été répondue qui devrait rester dans le chat, ici la question et la réponse n'ont aucun lien logique.
Mörre
Et pour répondre à la question d'origine, cela n'a pas d'importance pour Javascript. Cependant, Error(et les sous-classes) sont utilisées par convention. Par défaut, ils fournissent également une propriété de pile, bien qu'elle puisse être ajoutée manuellement à n'importe quelle autre. C'est donc surtout une convention, le déroulement du programme n'est pas affecté par ce que vous lancez, juste que vous throwen avez à tous les égards. Vous pourriez throw "grandmother down the stairs";et cela fonctionnerait de la même manière, sauf qu'il n'y aura pas de trace de pile attachée et de fonctions de gestion des erreurs, les journalistes, les débogueurs s'attendent Error, ou les propriétés fournies, pour être plus précis.
Mörre
104

lancer "I'm Evil"

throwmettra fin à l'exécution et exposera la chaîne de message lors de la capture de l'erreur.

try {
  throw "I'm Evil"
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e); //I'm Evil
}

La console après le lancer ne sera jamais atteinte à cause de l'arrêt.


lancer une nouvelle erreur ("I'm so sweet")

throw new Errorexpose un événement d'erreur avec deux paramètres nom et message . Il met également fin à l'exécution ultérieure

try {
  throw new Error("I'm Evil")
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e.name, e.message); //Error, I'm Evil
}

Nishchit Dhanani
la source
16
Qu'en est-il de la différence entre "jeter une erreur (" quel que soit ")" et "lancer une nouvelle erreur (" quel que soit ")" - les deux fonctionnent.
joedotnot
9
L'erreur est fonctionnelle, la nouvelle erreur est un constructeur. tous les deux fonctionnent même developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
5
@NishchitDhanani Je trouve étrange qu'un tel commentaire indéchiffrable et erroné suscite des votes. "L'erreur est fonctionnelle", ni "la nouvelle erreur est un constructeur" n'ont aucun sens et / ou sont faux. Dans ce contexte, on ne sait pas exactement ce que le lien est censé "prouver". C'est la page MDN pour Error, d'accord, où est le lien avec le commentaire? La moitié des personnes qui ont commenté et répondu à la question des PO auraient dû rester silencieuses.
Mörre
@ Mörre Voir cette section à Used as a functionpartir de ce lien ... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
C'est bon je l'ai. C'est une fonction .
Nishchit Dhanani
73

L'article suivant va peut-être plus en détail quant à ce qui est un meilleur choix; throw 'An error'ou throw new Error('An error'):

http://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

Cela suggère que ce dernier ( new Error()) est plus fiable, car les navigateurs comme Internet Explorer et Safari (incertain des versions) ne signalent pas correctement le message lors de l'utilisation du premier.

Cela entraînera une erreur, mais tous les navigateurs ne répondent pas de la manière attendue. Firefox, Opera et Chrome affichent chacun un message «exception non interceptée», puis incluent la chaîne de message. Safari et Internet Explorer lèvent simplement une erreur «exception non interceptée» et ne fournissent pas du tout la chaîne de message. De toute évidence, ce n'est pas optimal d'un point de vue de débogage.

Ed.
la source
36

Vous mentionnez d'abord ce code:

throw new Error('sample')

puis dans votre premier exemple vous écrivez:

throw new Error({'hehe':'haha'}) 

Le premier objet Error fonctionnerait réellement, car il attend une valeur de chaîne, dans ce cas «échantillon». Le second ne le serait pas parce que vous essayez de passer un objet et qu'il attend une chaîne.

L'objet d'erreur aurait la propriété "message", qui serait "échantillon".

IonicBurger
la source
12
Le second fonctionne, mais pas de manière très utile. Il exécute la toString()méthode sur l'objet transmis, ce qui entraîne [object Object]l'erreur (comme l'écrit l'Op).
cjn
15

vous pouvez throwcomme objet

throw ({message: 'This Failed'})

puis par exemple dans votre try/catch

try {
//
} catch(e) {
    console.log(e); //{message: 'This Failed'}
    console.log(e.message); //This Failed
}

ou simplement lancer une erreur de chaîne

throw ('Your error')

try {
//
} catch(e) {
    console.log(e); //Your error
}

throw new Error //only accept a string
Mbanda
la source
15

Le Errorconstructeur est utilisé pour créer un objet d'erreur. Les objets d'erreur sont levés lorsque des erreurs d'exécution se produisent. L'objet Error peut également être utilisé comme objet de base pour les exceptions définies par l'utilisateur.

Les erreurs définies par l'utilisateur sont lancées via l' throwinstruction. le contrôle du programme sera transmis au premier catchbloc de la pile d'appels.

La différence entre lancer une erreur avec et sans objet Error:


throw {'hehe':'haha'};

Dans chrome devtools ressemble à ceci:

entrez la description de l'image ici

Chrome nous dit que nous avons une erreur non détectée qui n'est qu'un objet JS. L'objet lui-même pourrait avoir des informations concernant l'erreur mais nous ne savons toujours pas immédiatement d'où elle vient. Pas très utile lorsque nous travaillons sur notre code et le débogage.


throw new Error({'hehe':'haha'}); 

Dans chrome devtools ressemble à ceci:

entrez la description de l'image ici

Une erreur renvoyée avec l'objet Error nous donne une trace de pile lorsque nous le développons. Cela nous donne des informations précieuses d'où vient précisément l'erreur, ce qui est souvent une information précieuse lors du débogage de votre code. Notez en outre que l'erreur indique [object Object] cela est dû au fait que le Errorconstructeur attend une chaîne de message comme premier argument. Lorsqu'il reçoit un objet, il le contraindra en une chaîne.

Willem van der Veen
la source
2

Comportement de réaction

Outre le reste des réponses, je voudrais montrer une différence dans React.

Si je lance un new Error()et que je suis en mode développement, j'obtiendrai un écran d'erreur et un journal de console. Si je jette une chaîne littérale, je ne la verrai que dans la console et je pourrai la manquer, si je ne regarde pas le journal de la console.

Exemple

Lancer une erreur se connecte à la console et affiche un écran d'erreur en mode développement (l'écran ne sera pas visible en production).

throw new Error("The application could not authenticate.");

Écran d'erreur en réaction

Alors que le code suivant se connecte uniquement à la console:

throw "The application could not authenticate.";
El Mac
la source