javascript - comprobando el tipo de error en JS
node.js (5)
En JS no parece posible verificar si un argumento pasado a una función es realmente del tipo ''error'' o una instancia de Error.
Por ejemplo, esto no es válido:
typeof err === ''error''
ya que solo hay 6 tipos posibles (en forma de cadenas):
El operador typeof devuelve información de tipo como una cadena.
Hay seis valores posibles que
typeof
devuelve:
"número", "cadena", "booleano", "objeto", "función" y "indefinido".
Pero qué pasa si tengo un caso de uso simple como este:
function errorHandler(err) {
if (typeof err === ''error'') {
throw err;
}
else {
console.error(''Unexpectedly, no error was passed to error handler. But here is the message:'',err);
}
}
Entonces, ¿cuál es la mejor manera de determinar si un argumento es una instancia de Error?
¿Es la
instanceof
operador de alguna ayuda?
Hice la pregunta original: la respuesta de @ Trott es seguramente la mejor.
Sin embargo, con JS como un lenguaje dinámico y con tantos entornos de tiempo de ejecución de JS, la
instanceof
operador puede fallar especialmente en el desarrollo front-end al cruzar límites como los iframes.
Ver:
https://github.com/mrdoob/three.js/issues/5886
Si está de acuerdo con la escritura de patos, esto debería ser bueno:
let isError = function(e){
return e && e.stack && e.message;
}
Personalmente, prefiero los idiomas con escritura estática, pero si está utilizando un lenguaje dinámico, es mejor adoptar un lenguaje dinámico como lo que es, en lugar de forzarlo a comportarse como un lenguaje con escritura estática.
si quisieras ser un poco más preciso, podrías hacer esto:
let isError = function(e){
return e && e.stack && e.message && typeof e.stack === ''string''
&& typeof e.message === ''string'';
}
O use esto para diferentes tipos de errores
function isError(val) {
return (!!val && typeof val === ''object'')
&& ((Object.prototype.toString.call(val) === ''[object Error]'')
|| (typeof val.message === ''string'' && typeof val.name === ''string''))
}
Puede usar el operador developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
var myError = new Error(''foo'');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false
Esto no funcionará si el error se arrojó en una ventana / marco / iframe diferente de donde está ocurriendo la verificación. Pero este es un enfoque simple y relativamente robusto de lo contrario.
Puede usar obj.constructor.name para verificar la "clase" de un objeto https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes
Por ejemplo
var error = new Error("ValidationError");
console.log(error.constructor.name);
La línea anterior registrará "Error", que es el nombre de la clase del objeto. Esto podría usarse con cualquier clase en JavaScript, si la clase no está usando una propiedad que se conoce con el nombre "nombre"
var myError = new Error(''foo'');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false
El único problema con esto es
myError instanceof Object // true
Una alternativa a esto sería usar la propiedad del constructor.
myError.constructor === Object // false
myError.constructor === String // false
myError.constructor === Boolean // false
myError.constructor === Symbol // false
myError.constructor === Function // false
myError.constructor === Error // true
Aunque debe tenerse en cuenta que esta coincidencia es muy específica, por ejemplo:
myError.constructor === TypeError // false