¿Cuál es la diferencia entre `throw new Error` y` throw someObject`?

378

Quiero escribir un controlador de errores común que detecte errores personalizados lanzados a propósito en cualquier instancia del código.

Cuando me throw new Error('sample')gustó en el siguiente código

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

El registro se muestra en Firefox como Error: [object Object]y no pude analizar el objeto.

Para el segundo, throwel registro se muestra como:Error: hehe

Mientras que cuando lo hice

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

la consola se mostró como: Object { hehe="haha"}en la que pude acceder a las propiedades de error.

¿Cuál es la diferencia?

¿Es la diferencia como se ve en el código? ¿La cadena similar se pasará como cadena y el objeto como objetos, pero la sintaxis será diferente?

No he explorado arrojar objetos de error ... solo había arrojado cadenas.

¿Hay alguna otra manera que los dos métodos mencionados anteriormente?

Jayapal Chandran
fuente
66
El problema con lanzar un nuevo error ({prop: val}) es que no es una construcción válida de error. El error tiene propiedades conocidas según lo discutido por Hemant.
grantwparks

Respuestas:

216

Aquí hay una buena explicación sobre el objeto The Error y arrojar sus propios errores.

El objeto de error

¿Qué podemos extraer de él en caso de error? El objeto Error en todos los navegadores admite las siguientes dos propiedades:

  • nombre: el nombre del error, o más específicamente, el nombre de la función constructora a la que pertenece el error.

  • mensaje: una descripción del error, que varía según el navegador.

La propiedad de nombre puede devolver seis valores posibles, que como se mencionan corresponden a los nombres de los constructores del error. Son:

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

Lanzar sus propios errores (excepciones)

En lugar de esperar a que ocurra uno de los 6 tipos de errores antes de que el control se transfiera automáticamente desde el bloque try al bloque catch, también puede lanzar explícitamente sus propias excepciones para forzar que eso suceda a pedido. Esto es excelente para crear sus propias definiciones de qué es un error y cuándo se debe transferir el control para capturar.

Hemant Metalia
fuente
44
Oh si. Esta es una buena cosa que me perdí antes de hacer esta pregunta. de todos modos, los usuarios que busquen información relacionada con esto serán eliminados. Ahora estoy claro de qué es qué. :) Gracias. Volveré a votar en unos días.
Jayapal Chandran
185
¿Ni siquiera responde la pregunta pero la respuesta más votada?
user9993
@ user9993 El usuario que hizo la pregunta estaba buscando una comprensión detallada según el chat en ese momento, por lo que, en consecuencia, se ha proporcionado una respuesta útil para el usuario. esa es la razón de los votos aceptados y más positivos.
Hemant Metalia
55
@HemantMetalia Pero tiene razón, la respuesta muestra ni siquiera el más mínimo intento de responder la pregunta de los OP como se indicó. Si se respondió una respuesta muy diferente en el chat que debería permanecer en el chat, aquí la pregunta y la respuesta no tienen ninguna conexión lógica.
Mörre
Y para responder a la pregunta original, no le importa a Javascript. Sin embargo, Error(y las subclases) se usan por convención. También proporcionan de manera predeterminada una propiedad de pila, aunque eso podría agregarse manualmente a cualquier otra. Por lo tanto, en realidad es principalmente una convención, el flujo del programa no se ve afectado por lo que arrojas, solo por lo que a ti te throwimporta. Podría throw "grandmother down the stairs";y funcionaría igual, excepto que no habrá un seguimiento de pila adjunto y funciones de manejo de errores, los reporteros, los depuradores esperan Error, o las propiedades que vienen, para ser más precisos.
Mörre
104

tirar "Soy malvado"

throwse terminará la ejecución ulterior y exponer cadena de mensaje en la captura del error.

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

La consola después del lanzamiento nunca se alcanzará debido a la terminación.


lanzar un nuevo error ("Soy tan dulce")

throw new Errorexpone un evento de error con dos parámetros nombre y mensaje . También termina la ejecución posterior

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
fuente
16
¿Qué pasa con la diferencia entre "lanzar error ('lo que sea')" y "lanzar nuevo error ('lo que sea')", ambos funcionan.
joedotnot
99
El error es funcional, el nuevo error es un constructor. ambos funcionan igual developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
55
@NishchitDhanani Me resulta extraño que un comentario tan indescifrable e incorrecto reciba votos positivos. Tanto "El error es funcional" como "El nuevo error es un constructor" no tienen ningún sentido y / o están equivocados. En ese contexto, no está claro qué se supone que debe "probar" exactamente el enlace. Es la página de MDN para Error, bueno, ¿dónde está la conexión con el comentario? La mitad de las personas que comentan y responden a las preguntas de los OP deberían haberse quedado en silencio.
Mörre
@ Mörre Vea esta sección Used as a functiondesde este enlace ... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
Esta bien, lo tengo. Es una funcion .
Nishchit Dhanani
73

El siguiente artículo tal vez entra en más detalles sobre cuál es una mejor opción; throw 'An error'o throw new Error('An error'):

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

Sugiere que este último ( new Error()) es más confiable, ya que los navegadores como Internet Explorer y Safari (no están seguros de las versiones) no informan correctamente el mensaje cuando usan el primero.

Al hacerlo, se generará un error, pero no todos los navegadores responden de la manera esperada. Firefox, Opera y Chrome muestran un mensaje de "excepción no detectada" y luego incluyen la cadena del mensaje. Safari e Internet Explorer simplemente lanzan un error de "excepción no detectada" y no proporcionan la cadena del mensaje en absoluto. Claramente, esto es subóptimo desde el punto de vista de depuración.

Ed.
fuente
36

Primero mencionas este código:

throw new Error('sample')

y luego en tu primer ejemplo escribes:

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

El primer objeto Error funcionaría realmente, porque está esperando un valor de cadena, en este caso 'muestra'. El segundo no lo haría porque está intentando pasar un objeto y está esperando una cadena.

El objeto de error tendría la propiedad "mensaje", que sería 'muestra'.

IonicBurger
fuente
12
El segundo sí funciona, pero no de una manera muy útil. Ejecuta el toString()método en el objeto pasado, lo que resulta [object Object]en el error (como escribió el Op).
cjn
15

puedes throwcomo objeto

throw ({message: 'This Failed'})

entonces por ejemplo en tu try/catch

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

o simplemente arrojar un error de cadena

throw ('Your error')

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

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

El Errorconstructor se usa para crear un objeto de error. Se lanzan objetos de error cuando se producen errores de tiempo de ejecución. El objeto Error también se puede usar como un objeto base para excepciones definidas por el usuario.

Los errores definidos por el usuario se generan a través de la throwdeclaración. el control del programa se pasará al primer catchbloque en la pila de llamadas.

La diferencia entre lanzar un error con y sin objeto Error:


throw {'hehe':'haha'};

En Chrome Devtools se ve así:

ingrese la descripción de la imagen aquí

Chrome nos dice que tenemos un error no detectado que solo es un objeto JS. El objeto en sí podría tener información sobre el error, pero aún no sabemos de inmediato de dónde vino. No es muy útil cuando trabajamos en nuestro código y lo depuramos.


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

En Chrome Devtools se ve así:

ingrese la descripción de la imagen aquí

Un error arrojado con el objeto Error nos da un seguimiento de la pila cuando lo expandimos. Esto nos da información valiosa de dónde proviene el error, que a menudo es información valiosa al depurar su código. Además, tenga en cuenta que el error dice que [object Object]esto se debe a que el Errorconstructor espera una cadena de mensaje como primer argumento. Cuando recibe un objeto, lo convertirá en una cadena.

Willem van der Veen
fuente
2

Comportamiento de reacción

Además del resto de las respuestas, me gustaría mostrar una diferencia en React.

Si lanzo new Error()ay estoy en modo de desarrollo, obtendré una pantalla de error y un registro de consola. Si lanzo un literal de cadena, solo lo veré en la consola y posiblemente lo pierda, si no estoy viendo el registro de la consola.

Ejemplo

Lanzar un error inicia sesión en la consola y muestra una pantalla de error mientras está en modo de desarrollo (la pantalla no será visible en producción).

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

Pantalla de error en reaccionar

Mientras que el siguiente código solo inicia sesión en la consola:

throw "The application could not authenticate.";
El mac
fuente