Qual é a diferença entre `throw new Error` e` throw someObject`?

378

Quero escrever um manipulador de erro comum que capture erros personalizados lançados de propósito em qualquer instância do código.

Quando eu throw new Error('sample')gostei no código a seguir

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

O log é exibido no Firefox Error: [object Object]e eu não consegui analisar o objeto.

Por um segundo, throwo log mostra como:Error: hehe

Considerando que quando eu fiz

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

o console mostrou como: Object { hehe="haha"}no qual eu consegui acessar as propriedades do erro.

Qual é a diferença?

A diferença é vista no código? Como string será apenas passada como string e objeto como objetos, mas a sintaxe será diferente?

Eu não explorei o lançamento do objeto de erro ... eu havia feito apenas o lançamento de strings.

Existe outra maneira além dos dois métodos mencionados acima?

Jayapal Chandran
fonte
6
O problema com o lançamento do novo erro ({prop: val}) é que não é uma construção válida do erro. O erro possui propriedades conhecidas, conforme discutido por Hemant.
Grantwparks
: relacionado cordas Throwing em vez de Errors
Bergi

Respostas:

216

Aqui está uma boa explicação sobre o objeto The Error e lançando seus próprios erros

O objeto de erro

Apenas o que podemos extrair dele em um evento de erro? O objeto Erro em todos os navegadores oferece suporte às duas propriedades a seguir:

  • nome: o nome do erro, ou mais especificamente, o nome da função de construtor à qual o erro pertence.

  • mensagem: Uma descrição do erro, com essa descrição variando, dependendo do navegador.

Seis valores possíveis podem ser retornados pela propriedade name, que conforme mencionado corresponde aos nomes dos construtores do erro. Eles são:

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

Lançando seus próprios erros (exceções)

Em vez de esperar que um dos 6 tipos de erros ocorra antes que o controle seja transferido automaticamente do bloco try para o bloco catch, você também pode lançar explicitamente suas próprias exceções para forçar isso a ocorrer sob demanda. Isso é ótimo para criar suas próprias definições sobre o que é um erro e quando o controle deve ser transferido para captura.

Hemant Metalia
fonte
4
Ai sim. essa é uma coisa boa que eu perdi antes de fazer essa pergunta. de qualquer maneira, os usuários que estiverem procurando informações relacionadas a isso serão limpos. Agora estou claro do que é o quê. :) Obrigado. voltarei a votar em alguns dias.
Jayapal Chandran
185
Nem sequer responde à pergunta ainda a resposta mais votada?
User9993 22/03
@ user9993 A pergunta feita pelo usuário estava procurando um entendimento detalhado conforme o bate-papo da época; portanto, a resposta foi fornecida e útil ao usuário. essa é a razão para votos aceitos e com maior número de votos.
Hemant Metalia 16/03/19
5
@ HemantMetalia Mas ele está certo, a resposta mostra nem a menor tentativa de responder à pergunta dos OPs, conforme indicado. Se uma resposta muito diferente no chat foi respondida e deve permanecer no chat, aqui a pergunta e a resposta não têm nenhuma conexão lógica.
Morre
E para responder à pergunta original, não importa para Javascript. No entanto, Error(e subclasses) são usados ​​por convenção. Por padrão, eles também fornecem uma propriedade de pilha, embora isso possa ser adicionado manualmente a qualquer outra. Então, na verdade, é na maioria das vezes convencional, o fluxo do programa não é afetado pelo que você joga, apenas por você throw. Você poderia throw "grandmother down the stairs";e funcionaria da mesma maneira, exceto que não haverá um rastreamento de pilha anexado e funções de tratamento de erros, repórteres, depuradores esperam Errorou as propriedades que o acompanham, para ser mais preciso.
Morre
104

jogue "eu sou mau"

throwirá terminar a posterior execução e expor cadeia de mensagem em captura o erro.

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

O console após o lançamento nunca será alcançado como causa de rescisão.


lançar novo erro ("eu sou tão doce")

throw new Errorexpõe um evento de erro com dois nomes e mensagem de parâmetro . Também encerra a execução adicional

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
fonte
16
o que dizer da diferença entre "throw Error ('Whatever')" e "throw New Error ('Whatever')" - ambos funcionam.
joedotnot
9
Erro é funcional, novo erro é um construtor. ambos funcionam da mesma maneira developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
5
@NishchitDhanani Acho estranho que um comentário tão indecifrável e errado seja votado. Tanto o "Erro é funcional", como o "novo Erro é um construtor" não fazem nenhum sentido e / ou estão errados. Nesse contexto, não está claro o que exatamente o link deve "provar". É a página MDN para Error, ok, onde está a conexão com o comentário? Metade das pessoas que comentam e respondem à pergunta dos OPs deveria ter permanecido em silêncio.
Morre
@ Mörre Consulte esta seção a Used as a functionpartir deste link ... developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
OK eu entendi. É uma função .
Nishchit Dhanani
73

O artigo a seguir talvez entre em mais detalhes sobre qual é a melhor escolha; 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/

Ele sugere que o último ( new Error()) é mais confiável, pois navegadores como o Internet Explorer e o Safari (sem certeza de versões) não relatam corretamente a mensagem ao usá-lo.

Isso fará com que um erro seja gerado, mas nem todos os navegadores respondem da maneira que você esperaria. Firefox, Opera e Chrome exibem uma mensagem de "exceção não capturada" e incluem a sequência de mensagens. O Safari e o Internet Explorer simplesmente lançam um erro de "exceção não capturada" e não fornecem a sequência da mensagem. Claramente, isso é subótimo do ponto de vista da depuração.

Ed.
fonte
36

Você primeiro mencionou este código:

throw new Error('sample')

e então no seu primeiro exemplo você escreve:

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

O primeiro objeto Error realmente funcionaria, porque está esperando um valor de string, neste caso 'sample'. O segundo não seria porque você está tentando passar um objeto e espera uma string.

O objeto de erro teria a propriedade "message", que seria 'sample'.

IonicBurger
fonte
12
O segundo funciona, mas não de uma maneira muito útil. Ele executa o toString()método no objeto transmitido, resultando no [object Object]erro (como o Op escreveu).
CJN
15

você pode throwcomo objeto

throw ({message: 'This Failed'})

então, por exemplo, no seu try/catch

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

ou apenas lançar um erro de string

throw ('Your error')

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

throw new Error //only accept a string
Mbanda
fonte
15

O Errorconstrutor é usado para criar um objeto de erro. Os objetos de erro são lançados quando ocorrem erros de tempo de execução. O objeto Erro também pode ser usado como objeto básico para exceções definidas pelo usuário.

Os erros definidos pelo usuário são gerados por meio da throwinstrução o controle do programa será passado para o primeiro catchbloco na pilha de chamadas.

A diferença entre lançar um erro com e sem o objeto Error:


throw {'hehe':'haha'};

No chrome, as devtools são assim:

insira a descrição da imagem aqui

O Chrome nos diz que temos um erro não detectado, que é apenas um objeto JS. O objeto em si pode ter informações sobre o erro, mas ainda não sabemos imediatamente de onde ele veio. Não é muito útil quando estamos trabalhando em nosso código e depurando-o.


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

No chrome, as devtools são assim:

insira a descrição da imagem aqui

Um erro lançado com o objeto Error nos fornece um rastreamento de pilha quando o expandimos. Isso nos fornece informações valiosas, de onde veio o erro, que geralmente é informações valiosas ao depurar seu código. Observe também que o erro diz que [object Object]isso ocorre porque o Errorconstrutor espera uma sequência de mensagens como primeiro argumento. Quando recebe um objeto, ele o coage em uma string.

Willem van der Veen
fonte
2

Comportamento de reação

Além do restante das respostas, gostaria de mostrar uma diferença no React.

Se eu jogar ae new Error()estiver no modo de desenvolvimento, receberei uma tela de erro e um log do console. Se eu lançar uma string literal, eu a verei apenas no console e possivelmente a perderá, se não estiver assistindo o log do console.

Exemplo

Lançar um log de erros no console e mostra uma tela de erro enquanto estiver no modo de desenvolvimento (a tela não estará visível na produção).

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

Tela de erro ao reagir

Enquanto o código a seguir apenas efetua login no console:

throw "The application could not authenticate.";
El Mac
fonte