comprobando el tipo de error en JS

Resuelto Alexander Mills asked hace 9 años • 12 respuestas

En JS no parece posible comprobar 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 sólo 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" e "indefinido".

MSDN

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?

¿ El instanceofoperador es de alguna ayuda?

Alexander Mills avatar May 27 '15 04:05 Alexander Mills
Aceptado

Puede utilizar el instanceofoperador (¡pero consulte la advertencia a continuación!).

var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false

Lo anterior no funcionará si el error se produjo en una ventana/marco/iframe diferente al lugar donde se realiza la verificación. En ese caso, la instanceof Errorverificación devolverá falso, incluso para un Errorobjeto. En ese caso, el método más sencillo es escribir con pato.

if (myError && myError.stack && myError.message) {
  // it's an error, probably
}

Sin embargo, la escritura pato puede producir falsos positivos si tiene objetos que no contienen errores stacky que contienen messagepropiedades.

Trott avatar May 26 '2015 21:05 Trott

Hice la pregunta original: la respuesta de @Trott es seguramente la mejor.

Sin embargo, dado que JS es un lenguaje dinámico y hay tantos entornos de ejecución de JS, el instanceofoperador puede fallar, especialmente en el desarrollo front-end, al cruzar límites como los iframes. Ver: https://github.com/mrdoob/tres.js/issues/5886

Si estás de acuerdo con la escritura de pato, esto debería ser bueno:

let isError = function(e){
   return e && e.stack && e.message;
};

Personalmente prefiero los lenguajes escritos estáticamente, pero si estás usando un lenguaje dinámico, es mejor adoptar un lenguaje dinámico tal como es, en lugar de forzarlo a comportarse como un lenguaje escrito estáticamente.

Si quisieras ser un poco más preciso, podrías hacer esto:

       let isError = (e) => {
         return e && 
                e.stack && 
                e.message && 
                typeof e.stack === 'string' && 
                typeof e.message === 'string';
        };
Alexander Mills avatar Aug 03 '2017 23:08 Alexander Mills

Puede utilizarlo Object.prototype.toStringpara comprobar fácilmente si un objeto es un objeto Error, lo que también funcionará para diferentes fotogramas.

function isError(obj){
    return Object.prototype.toString.call(obj) === "[object Error]";
}

function isError(obj){
    return Object.prototype.toString.call(obj) === "[object Error]";
}
console.log("Error:", isError(new Error));
console.log("RangeError:", isError(new RangeError));
console.log("SyntaxError:", isError(new SyntaxError));
console.log("Object:", isError({}));
console.log("Array:", isError([]));
Expandir fragmento

Este comportamiento está garantizado por la especificación del lenguaje ECMAScript.

Object.prototype.toString:

Cuando se llama al método toString, se siguen los siguientes pasos:

  1. Si este valor no está definido, devuelve "[objeto indefinido]".
  2. Si este valor es nulo, devuelve "[objeto nulo]".
  3. Sea O el resultado de llamar a ToObject pasando este valor como argumento.
  4. Sea clase el valor de la propiedad interna [[Clase]] de O.
  5. Devuelve el valor de Cadena que es el resultado de concatenar las tres Cadenas "[objeto", clase y "]".

Propiedades de las instancias de error :

Las instancias de error heredan propiedades del objeto prototipo Error y su [[Class]]valor de propiedad interna es "Error". Las instancias de error no tienen propiedades especiales.

Unmitigated avatar May 22 '2020 15:05 Unmitigated