Entonces tengo estas clases que uso para manejar errores en diferentes escenarios así:
export class APIError extends Error { public readonly statusCode: number; public readonly message: string; constructor(statusCode?: number, message?: string) { super(message); Object.setPrototypeOf(this, APIError.prototype); if (typeof statusCode === 'string') { message = statusCode; statusCode = null; } this.statusCode = statusCode || 500; this.message = message || 'Internal Server Error'; } public toJSON(): JsonData { return { statusCode: this.statusCode, message: this.message, }; } } export class NotFound extends APIError { constructor(message?: string) { super(404, 'Not Found'); Object.setPrototypeOf(this, NotFound.prototype); } } export class StreamNotFound extends NotFound { constructor() { super('Stream Not Found'); Object.setPrototypeOf(this, StreamNotFound.prototype); } }Y luego tengo este método abstracto de actualización:
public update(id: string, updateThing: T): T { if (!updateThing) return; const thing: T = this.get(id); if (!thing) { throw new NotFound(`${this.displayName} could not be found.`); } ....En mi controlador, estoy tratando de detectar el error y luego obtener su instancia de esta manera:
} catch (e) { const statusCode = (e instanceof StreamNotFound) ? 404 : null; throw HttpController.handleError(e, statusCode); }Pero statusCode siempre devolverá un valor nulo, aunque streamNotFound amplíe NotFound, y Notfound esté siendo utilizado por el método abstracto Actualizar.
Como puede ver, estoy agregando Object.setPrototypeOf(this, StreamNotFound.prototype); en cada uno de los métodos, así que me pregunto por qué no funciona como se esperaba.
Una subclase siempre será una instanceof de sí misma y de cualquiera de sus clases principales. Sin embargo, lo contrario no es cierto: una clase padre no es una instanceof de ninguna de sus subclases.
En este ejemplo, StreamNotFound instanceof NotFound === true . Sin embargo, una clase padre no es explícitamente una instanceof de ninguna de sus subclases. Aquí, NotFound instanceof StreamNotFound === false .
En su controlador, está throw una instancia de NotFound , que nunca será una instanceof StreamNotFound , ya que está más arriba en la cadena de prototipos que sus subclases.
En el siguiente ejemplo simplificado, Bar extiende a Foo como una subclase, por lo tanto:
Foo instanceof Foo === trueBar instanceof Foo === trueBar instanceof Bar === trueFoo instanceof Bar === false class Foo { constructor() { } } class Bar extends Foo { constructor() { super(); } } const obj1 = new Foo(); const obj2 = new Bar(); console.log("Bar instanceof Bar: " + (obj2 instanceof Bar)); console.log("Bar instanceof Foo: " + (obj2 instanceof Foo)); console.log("Foo instanceof Bar: " + (obj1 instanceof Bar));