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 typeofdevuelve:
"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 el instanceofoperador de alguna ayuda?
javascript
node.js
Alexander Mills
fuente
fuente

err instanceof Errorerr(digamos) un iframe, pero luego lo pasa a la ventana principal para que lo entregue, obtendrá(err instanceof Error) === false. Esto se debe a que el iframe y su ventana principal tienenErrorprototipos de objetos distintos . Del mismo modo, un objeto comoobj = {};will, cuando se pasa a una función que se ejecuta en una ventana diferente, yeild(obj instanceof Object)===false. (Incluso peor, en IE, si mantiene una referencia a obj después de que su ventana se destruye o navega, ¡tratar de llamar a los prototipos de objetos comoobj.hasOwnProperty()arrojará errores!)catch((err)=>{if (err === ENOENT)devuelveENOENT is not definederror?Respuestas:
Puede usar el
instanceofoperador (¡pero vea la advertencia a continuación!).Lo anterior no funcionará si el error se arrojó en una ventana / marco / iframe diferente de donde está ocurriendo la verificación. En ese caso, el
instanceof Errorcheque devolverá falso, incluso para unErrorobjeto. En ese caso, el enfoque más fácil es escribir el pato.Sin embargo, la escritura de pato puede producir falsos positivos si tiene objetos que contienen errores
stackymessagepropiedades.fuente
ReferenceErrorinstancia. Estás comprobando elReferenceErrorobjeto global . Prueba esto: setry { foo } catch (e) { console.log(e instanceof Error) }registratrue. Si está tratando de verificar elReferenceErrorobjeto global por alguna razón, puede usarError.isPrototypeOf(ReferenceError)ReferenceErrorinstancias no eran instanciasError. Esto se debió a una llamada alvm.runInNewContext()nodo in, donde se redefinen todos los prototipos estándar. Todos mis resultados no fueron instancias de objetos estándar. Estaba buscando en SO sobre esto, y caí en este hilo :)const error = (err instanceof Error || err instanceof TypeError) ? err : new Error(err.message ? err.message : err);instanceoftipo específico de error?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, el
instanceofoperador puede fallar especialmente en el desarrollo front-end cuando cruza límites como iframes. Ver: https://github.com/mrdoob/three.js/issues/5886Si está de acuerdo con la escritura del pato, esto debería ser bueno:
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:
fuente
instanceofoperador falla en algunos casos, consulte el artículo vinculado.Error,ReferenceError, ...). Y en mi entorno, elinstanceoffalla miserablemente en muchas circunstancias.El único problema con esto es
Una alternativa a esto sería usar la propiedad del constructor.
Aunque debe tenerse en cuenta que esta coincidencia es muy específica, por ejemplo:
fuente
Puede usar
Object.prototype.toStringpara verificar fácilmente si un objeto es unError, que también funcionará para diferentes marcos.fuente
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
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 usa una propiedad que se llame "nombre"
fuente
Gracias @Trott por su código, acabo de usar el mismo código y lo agregué con un ejemplo de trabajo en tiempo real para beneficio de otros.
fuente
O use esto para diferentes tipos de errores
fuente