Por alguna razón, parece que la delegación de constructor no funciona en el siguiente fragmento:
function NotImplementedError() {
Error.apply(this, arguments);
}
NotImplementedError.prototype = new Error();
var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")
Ejecutar esto da The message is: ''
. ¿Alguna idea de por qué, o si hay una mejor manera de crear una nueva Error
subclase? ¿Hay algún problema con apply
el Error
constructor nativo que no conozco?
javascript
exception
cdleary
fuente
fuente
Respuestas:
Actualice su código para asignar su prototipo al Error.prototype y la instancia de y sus afirmaciones funcionan.
Sin embargo, simplemente lanzaría su propio objeto y simplemente verificaría la propiedad del nombre.
Editar basado en comentarios
Después de mirar los comentarios y tratar de recordar por qué asignaría un prototipo en
Error.prototype
lugar denew Error()
como lo hizo Nicholas Zakas en su artículo , creé un jsFiddle con el siguiente código:La salida de la consola fue esta.
Esto confirma que el "problema" con el que me encontré fue que la propiedad de pila del error era el número de línea donde
new Error()
se creó y no dóndethrow e
ocurrió. Sin embargo, eso puede ser mejor que tener el efecto secundario de unaNotImplementedError.prototype.name = "NotImplementedError"
línea que afecta el objeto Error.Además,
NotImplementedError2
tenga en cuenta que , cuando no configuro.name
explícitamente, es igual a "Error". Sin embargo, como se menciona en los comentarios, debido a que esa versión establece el prototiponew Error()
, podría configurarNotImplementedError2.prototype.name = "NotImplementedError2"
y estar bien.fuente
Error.prototype
directamente es probablemente una mala forma. Si más tarde desea agregar unNotImplementedError.prototype.toString
objeto alias ahoraError.prototype.toString
, mejor hacerloNotImplementedError.prototype = new Error()
.subclass.prototype = new Error()
está en mal estado. Se supone que debes usarsubclass.prototype = Object.create(superclass.prototype)
en su lugar. Espero que también pueda solucionar el problema de seguimiento de la pila.this.stack = new Error().stack;
NotImplementedError.prototype = Error.prototype;
no haceinstanceof
tratarNotImplementedError
como una subclase deError
, haceinstanceof
tratarlos como exactamente la misma clase. Si pega el código anterior en su consola e intentanew Error() instanceof NotImplementedError
, obtendrátrue
, lo cual es claramente incorrecto.Todas las respuestas anteriores son terriblemente horribles, de verdad. ¡Incluso el que tiene 107 ups! La verdadera respuesta está aquí chicos:
Heredar del objeto Error: ¿dónde está la propiedad del mensaje?
TL; DR:
R. La razón por la
message
que no se establece es queError
es una función que devuelve un nuevo objeto Error y no manipulathis
de ninguna manera.B. La forma de hacer esto bien es devolver el resultado de la aplicación desde el constructor, así como configurar el prototipo de la manera complicada habitual de javascripty:
Probablemente podría hacer algunos trucos para enumerar todas las propiedades no enumerables del
tmp
Error para establecerlas en lugar de establecerlas explícitamentestack
ymessage
, pero el truco no es compatible, es decir, <9fuente
return this
en un constructor.temp.name = this.name = 'MyError'
, puedes hacerlotemp.name = this.name = this.constructor.name
. De esa manera también funcionará para subclases deMyError
.En ES2015, puede
class
hacer esto limpiamente:Esto no modifica el
Error
prototipo global , le permite personalizarmessage
,name
y otros atributos, y capta adecuadamente la pila. También es bastante legible.Por supuesto, es posible que deba usar una herramienta como
babel
si su código se ejecutara en navegadores más antiguos.fuente
Si alguien tiene curiosidad sobre cómo crear un error personalizado y obtener el seguimiento de la pila:
fuente
Esta sección del estándar puede explicar por qué la
Error.apply
llamada no inicializa el objeto:En este caso, la
Error
función probablemente determina que no se llama como un constructor, por lo que devuelve una nueva instancia de Error en lugar de inicializar elthis
objeto.Las pruebas con el siguiente código parecen demostrar que esto es lo que está sucediendo:
La siguiente salida se genera cuando se ejecuta esto:
fuente
this
enError.apply(this, arguments);
? Estoy diciendo que la llamada al Error aquí está construyendo un nuevo objeto, que se tira; no inicializando el objeto ya construido al que está asignadonie
.NotImplementedError
implementación devolver lareturned
variable?fuente
Tuve un problema similar a esto. Mi error debe ser
instanceof
ambosError
yNotImplemented
, y también debe generar un seguimiento coherente en la consola.Mi solución:
Resultado de ejecutar con node.js:
El error supera los 3 criterios, y aunque la
stack
propiedad no es estándar, es compatible con la mayoría de los navegadores más nuevos, lo cual es aceptable en mi caso.fuente
Según Joyent, no deberías meterte con la propiedad de la pila (que veo en muchas respuestas aquí), ya que tendrá un impacto negativo en el rendimiento. Aquí está lo que dicen:
Me gusta y me gustaría mencionar su idea de envolver el error original que es un buen reemplazo para pasar a la pila.
Así que aquí es cómo creo un error personalizado, teniendo en cuenta lo mencionado anteriormente:
versión es5:
versión es6:
He puesto mi solución en un módulo, aquí está: https://www.npmjs.com/package/rerror
fuente
Me gusta hacerlo así:
"{code}: {message}"
error.code
verificar o analizar un código es mejor en código que verificar un mensaje, que quizás desee localizar, por ejemploerror.message
como una alternativa aerror.toString()
fuente
Simplemente tuve que implementar algo como esto y descubrí que la pila se perdió en mi propia implementación de error. Lo que tuve que hacer fue crear un error ficticio y recuperar la pila de eso:
fuente
Usé el patrón de constructor para crear el nuevo objeto de error. Definí la cadena del prototipo como una
Error
instancia. Consulte la referencia del constructor Error MDN .Puede consultar este fragmento en esta esencia .
IMPLEMENTACIÓN
USO
El constructor CustomError puede recibir muchos argumentos para construir el mensaje, p. Ej.
Y así es como se ve el error personalizado:
fuente
El constructor debe ser como un método de fábrica y devolver lo que desea. Si necesita métodos / propiedades adicionales, puede agregarlos al objeto antes de devolverlo.
Aunque no estoy seguro de por qué necesitarías hacer esto. ¿Por qué no solo usar
new Error...
? Las excepciones personalizadas realmente no agregan mucho en JavaScript (o probablemente en cualquier lenguaje sin tipo).fuente
Esto se implementa muy bien en el Cesium DeveloperError:
En su forma simplificada:
fuente
error instanceof Error
prueba, lo que puede ser útil.Esta es mi implementación:
Ejemplo de uso # 1:
Ejemplo de uso # 2:
fuente
A expensas de no poder usar
instanceof
, lo siguiente conserva el seguimiento de la pila original y no usa ningún truco no estándar.fuente
fixError
función anterior. Agregar unnew
al llamarlo simplemente crearía un objeto que se descarta.Otra alternativa, podría no funcionar en todos los entornos. Al menos aseguró que funciona en nodejs 0.8 Este enfoque utiliza una forma no estándar de modificar el prototipo interno
fuente
Si está utilizando Node / Chrome. El siguiente fragmento obtendrá su extensión que cumple con los siguientes requisitos.
err instanceof Error
err instanceof CustomErrorType
[CustomErrorType]
cuando se crea con un mensaje[CustomErrorType: message]
cuando se crea sin un mensajeif
declaraciones y listo .Retazo
Uso
Salida
fuente
Lo siguiente funcionó para mí tomado de la documentación oficial de Mozilla Error .
fuente
Pruebe un nuevo objeto prototipo para cada instancia del tipo de error definido por el usuario. Permite que las
instanceof
comprobaciones se comporten como de costumbre, además el tipo y el mensaje se informan correctamente en Firefox y V8 (Chome, nodejs).Tenga en cuenta que una entrada adicional precederá a la pila correcta.
fuente
var a = new NotImplementedError('a'), b = new NotImplementedError('b');
. Ahoraa instanceof NotImplementedError == false
yb instanceof NotImplementedError == true
Esta es la forma más rápida de hacerlo:
fuente
De manera más fácil. Puede hacer que su objeto herede del objeto Error. Ejemplo:
lo que estamos haciendo es usar la función call () que llama al constructor de la clase Error, por lo que es básicamente lo mismo que implementar una herencia de clase en otros lenguajes orientados a objetos.
fuente
MDN tiene un excelente ejemplo :
fuente