Qual è la differenza tra `throw new Error` e` throw someObject`?


378

Voglio scrivere un gestore di errori comune che rileverà errori personalizzati lanciati di proposito in qualsiasi istanza del codice.

Quando mi è throw new Error('sample')piaciuto nel seguente codice

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

Il registro mostra in Firefox come Error: [object Object]e non ho potuto analizzare l'oggetto.

Per il secondo throwil registro mostra come:Error: hehe

Mentre quando l'ho fatto

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

la console ha mostrato come: Object { hehe="haha"}in cui sono stato in grado di accedere alle proprietà dell'errore.

Qual è la differenza?

La differenza si vede nel codice? Come stringa verrà appena passata come stringa e oggetto come oggetti ma la sintassi sarà diversa?

Non ho esplorato il lancio di un oggetto di errore ... Avevo fatto solo il lancio di stringhe.

Esiste un modo diverso dai due metodi sopra menzionati?


6
Il problema con il lancio di un nuovo errore ({prop: val}) è che non è una costruzione valida di errore. L'errore ha proprietà note come discusso da Hemant.
grantwparks

Risposte:


216

Ecco una buona spiegazione sull'oggetto Error e sul lancio dei propri errori

L'oggetto errore

Proprio quello che possiamo estrarre da esso in caso di errore? L'oggetto Error in tutti i browser supporta le seguenti due proprietà:

  • name: il nome dell'errore, o più specificamente, il nome della funzione di costruzione a cui appartiene l'errore.

  • messaggio: una descrizione dell'errore, con questa descrizione che varia a seconda del browser.

Sei valori possibili possono essere restituiti dalla proprietà name, che come detto corrisponde ai nomi dei costruttori dell'errore. Loro sono:

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()).

Lanciare i propri errori (eccezioni)

Invece di attendere che si verifichi uno dei 6 tipi di errori prima che il controllo venga trasferito automaticamente dal blocco try al blocco catch, è anche possibile generare esplicitamente le proprie eccezioni per forzare che ciò avvenga su richiesta. Questo è ottimo per creare le tue definizioni di cosa sia un errore e quando il controllo dovrebbe essere trasferito per catturare.


4
Oh si. questa è una buona cosa che mi mancava prima di porre questa domanda. comunque gli utenti che cercano informazioni relative a questo verranno cancellati. Ora sono chiaro di cosa sia cosa. :) Grazie. tornerò a votare tra qualche giorno.
Jayapal Chandran,

185
Non risponde nemmeno alla domanda, la risposta più votata?
user9993

@ user9993 L'utente che ha fatto la domanda stava cercando una comprensione dettagliata come per chat in quel momento, quindi di conseguenza è stata fornita una risposta e utile per l'utente. questo è il motivo dei voti accettati e più votati.
Hemant Metalia

5
@HemantMetalia Ma ha ragione, la risposta non mostra nemmeno il minimo tentativo di rispondere alla domanda dei PO come indicato. Se viene fornita una risposta molto diversa nella chat che dovrebbe rimanere nella chat, qui la domanda e la risposta non hanno alcuna connessione logica.
Mörre,

E per rispondere alla domanda originale, non importa per Javascript. Tuttavia, Error(e sottoclassi) vengono utilizzati per convenzione. Per impostazione predefinita, forniscono anche una proprietà dello stack, sebbene ciò possa essere aggiunto manualmente a qualsiasi altro. Quindi è per lo più una convenzione, il flusso del programma non è influenzato da ciò che si lancia, solo che tu throwa tutti gli effetti . Potresti throw "grandmother down the stairs";e funzionerebbe allo stesso modo, tranne per il fatto che non ci sarà una traccia dello stack collegata e funzioni di gestione degli errori, che i giornalisti, i debugger si aspettano Erroro le proprietà che ne derivano, per essere più precisi.
Mörre,

104

getta "I'm Evil"

throwsi terminerà l'ulteriore esecuzione & esporre stringa di messaggio sulla cattura l'errore.

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

La console dopo il lancio non sarà mai raggiunta a causa della risoluzione.


genera un nuovo errore ("Sono così dolce")

throw new Errorespone un evento di errore con due parametri nome e messaggio . Termina anche ulteriori esecuzioni

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
}


16
che dire della differenza tra "buttare errore ('qualunque')" e "lanciare nuovo errore ('qualunque')" - entrambi funzionano.
Joedotnot

9
L'errore è funzionale, il nuovo errore è un costruttore. funzionano entrambi allo stesso modo developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani

5
@NishchitDhanani Trovo strano che un commento così indecifrabile e sbagliato ottenga voti. Sia "Errore è funzionale", né "nuovo errore è un costruttore" non ha alcun senso e / o sono sbagliati. In tale contesto non è chiaro quale sia esattamente il motivo per cui "il collegamento" dovrebbe "dimostrare". È la pagina MDN per Error, okay, dov'è la connessione al commento? La metà delle persone che commentano e rispondono alla domanda dei PO dovrebbero essere rimaste in silenzio.
Mörre,

@ Mörre Vedi questa sezione Used as a functionda questo link ... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani,

Okay ho capito. È una funzione .
Nishchit Dhanani,

73

Il seguente articolo forse fornisce alcuni dettagli in più su quale sia una scelta migliore; throw 'An error'oppure throw new Error('An error'):

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

Suggerisce che quest'ultimo ( new Error()) sia più affidabile, poiché browser come Internet Explorer e Safari (non sicuri delle versioni) non segnalano correttamente il messaggio quando si utilizza il primo.

In questo modo verrà generato un errore, ma non tutti i browser risponderanno come ti aspetteresti. Firefox, Opera e Chrome visualizzano ciascuno un messaggio di "eccezione non rilevata" e quindi includono la stringa di messaggio. Safari e Internet Explorer generano semplicemente un errore di "eccezione non rilevata" e non forniscono affatto la stringa di messaggio. Chiaramente, questo non è ottimale dal punto di vista del debug.


36

Prima menzioni questo codice:

throw new Error('sample')

e poi nel tuo primo esempio scrivi:

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

Il primo oggetto Error funzionerebbe effettivamente, perché si aspetta un valore di stringa, in questo caso 'campione'. Il secondo no perché stai provando a passare un oggetto e si aspetta una stringa.

L'oggetto errore avrebbe la proprietà "message", che sarebbe "campione".


12
Il secondo funziona, ma non in modo molto utile. Esegue il toString()metodo sull'oggetto passato, causando [object Object]l'errore (come ha scritto l'Op).
cjn


15

puoi throwcome oggetto

throw ({message: 'This Failed'})

quindi ad esempio nel tuo try/catch

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

o semplicemente lanciare un errore di stringa

throw ('Your error')

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

throw new Error //only accept a string

15

Il Errorcostruttore viene utilizzato per creare un oggetto errore. Gli oggetti errore vengono generati quando si verificano errori di runtime. L'oggetto Error può anche essere usato come oggetto base per eccezioni definite dall'utente.

Gli errori definiti dall'utente vengono generati tramite l' throwistruzione. il controllo del programma verrà passato al primo catchblocco nello stack di chiamate.

La differenza tra generare un errore con e senza oggetto Error:


throw {'hehe':'haha'};

In chrome devtools si presenta così:

inserisci qui la descrizione dell'immagine

Chrome ci dice che abbiamo un errore non rilevato che è solo un oggetto JS. L'oggetto stesso potrebbe contenere informazioni sull'errore ma non sappiamo ancora da dove provenga. Non molto utile quando stiamo lavorando sul nostro codice e il debug.


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

In chrome devtools si presenta così:

inserisci qui la descrizione dell'immagine

Un errore generato con l'oggetto Error ci fornisce una traccia dello stack quando lo espandiamo. Questo ci fornisce informazioni preziose da cui proviene esattamente l'errore, che spesso sono informazioni preziose durante il debug del codice. Si noti inoltre che l'errore dice [object Object], questo perché il Errorcostruttore si aspetta una stringa di messaggio come primo argomento. Quando riceve un oggetto, lo forzerà in una stringa.


2

Reagire al comportamento

A parte il resto delle risposte, vorrei mostrare una differenza in React.

Se lancio new Error()ae sono in modalità sviluppo, visualizzerò una schermata di errore e un registro della console. Se lancio letteralmente una stringa, la vedrò solo nella console e probabilmente la mancherò, se non guardo il registro della console.

Esempio

Lancio di un errore accede alla console e mostra una schermata di errore in modalità di sviluppo (la schermata non sarà visibile in produzione).

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

Schermata di errore in reagire

Considerando che il seguente codice accede solo alla console:

throw "The application could not authenticate.";
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.