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 el instanceof
operador de alguna ayuda?
javascript
node.js
Alexander Mills
fuente
fuente
err instanceof Error
err
(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 tienenError
prototipos 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 defined
error?Respuestas:
Puede usar el
instanceof
operador (¡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 Error
cheque devolverá falso, incluso para unError
objeto. 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
stack
ymessage
propiedades.fuente
ReferenceError
instancia. Estás comprobando elReferenceError
objeto global . Prueba esto: setry { foo } catch (e) { console.log(e instanceof Error) }
registratrue
. Si está tratando de verificar elReferenceError
objeto global por alguna razón, puede usarError.isPrototypeOf(ReferenceError)
ReferenceError
instancias 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);
instanceof
tipo 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
instanceof
operador 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
instanceof
operador falla en algunos casos, consulte el artículo vinculado.Error
,ReferenceError
, ...). Y en mi entorno, elinstanceof
falla 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.toString
para 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