¿Cuál es la diferencia entre "lanzar un nuevo error" y "lanzar algún objeto"?
Quiero escribir un controlador de errores común que detecte errores personalizados generados intencionalmente 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 Error: [object Object]
y no pude analizar el objeto.
Para el segundo, throw
el registro se muestra como:Error: hehe
Mientras que cuando lo hice
try {
throw ({'hehe':'haha'});
} catch(e) {
alert(e);
console.log(e);
}
la consola mostró como: Object { hehe="haha"}
en el que pude acceder a las propiedades del error.
¿Cuál es la diferencia?
¿La diferencia es como se ve en el código? ¿La cadena se pasará simplemente como cadena y el objeto como objetos, pero la sintaxis será diferente?
No he explorado el lanzamiento de objetos de error... Solo había lanzado hilos.
¿Existe alguna otra forma además de los dos métodos mencionados anteriormente?
La diferencia entre 'lanzar un nuevo error' y 'lanzar un objeto' en javascript es que lanzar un nuevo error envuelve el error que se le pasa en el siguiente formato:
{ nombre: 'Error', mensaje: 'Cadena que pasas en el constructor' }
Throw someObject arrojará el objeto tal como está y no permitirá ninguna ejecución adicional de código desde el bloque try, es decir, lo mismo que arrojar un nuevo error.
Aquí hay una buena explicación sobre el objeto Error y cómo generar 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 dos propiedades siguientes:
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, y esta descripción varía según el navegador.
La propiedad name puede devolver seis valores posibles, que como se mencionó corresponden a los nombres de los constructores del error. Ellos 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 tus 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 del bloque try al bloque catch, también puede generar explícitamente sus propias excepciones para forzar que eso suceda bajo demanda. Esto es excelente para crear sus propias definiciones de qué es un error y cuándo se debe transferir el control a la captura.
tira "soy malvado"
throw
finalizará la ejecución adicional y expondrá la cadena del mensaje al detectar el error.
try {
throw "I'm Evil"
console.log("You'll never reach to me", 123465)
} catch (e) {
console.log(e); // I'm Evil
}
Nunca se alcanzará la consola después del lanzamiento , causa de terminación.
arrojar un nuevo error ("Soy malvado")
throw new Error
expone un evento de error con dos parámetros nombre y mensaje . También pone fin a la ejecución 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
}
tirar error("Soy malvado")
Y para completar, esto también funciona, aunque técnicamente no es la forma correcta de hacerlo.
try {
throw 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
}
console.log(typeof(new Error("hello"))) // object
console.log(typeof(Error)) // function
El siguiente artículo quizás entre en más detalles sobre cuál es la 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 navegadores como Internet Explorer y Safari (no estoy seguro de las versiones) no informan correctamente el mensaje cuando usan el primero.
Hacerlo provocará un error, pero no todos los navegadores responden de la manera esperada. Firefox, Opera y Chrome muestran cada uno un mensaje de "excepción no detectada" y luego incluyen la cadena del mensaje. Safari e Internet Explorer simplemente arrojan un error de "excepción no detectada" y no proporcionan ninguna cadena de mensaje. Claramente, esto no es óptimo desde el punto de vista de la depuración.
TLDR: son equivalentes Error(x) === new Error(x)
.
// this:
const x = Error('I was created using a function call!');
// has the same functionality as this:
const y = new Error('I was constructed via the "new" keyword!');
fuente: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
throw
y throw Error
son funcionalmente equivalentes. Pero cuando los capturas y los serializas, console.log
no se serializan exactamente de la misma manera:
throw 'Parameter is not a number!';
throw new Error('Parameter is not a number!');
throw Error('Parameter is not a number!');
Console.log(e)
de lo anterior producirá 2 resultados diferentes:
Parameter is not a number!
Error: Parameter is not a number!
Error: Parameter is not a number!