So I have these classes that I use to handle errors in different scenerios like so:
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);
}
}
And then I have this update abstract method:
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.`);
}
....
In my controller, I'm trying to catch the error and then get it's instance like so:
} catch (e) {
const statusCode = (e instanceof StreamNotFound) ? 404 : null;
throw HttpController.handleError(e, statusCode);
}
But statusCode will always return null, even though streamNotFound extends NotFound, and Notfound is being used by the Update abstract method.
As you can see, I'm adding the Object.setPrototypeOf(this, StreamNotFound.prototype);
on each of the methods, so I'm wondering why it is not working as expected?
So I have these classes that I use to handle errors in different scenerios like so:
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);
}
}
And then I have this update abstract method:
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.`);
}
....
In my controller, I'm trying to catch the error and then get it's instance like so:
} catch (e) {
const statusCode = (e instanceof StreamNotFound) ? 404 : null;
throw HttpController.handleError(e, statusCode);
}
But statusCode will always return null, even though streamNotFound extends NotFound, and Notfound is being used by the Update abstract method.
As you can see, I'm adding the Object.setPrototypeOf(this, StreamNotFound.prototype);
on each of the methods, so I'm wondering why it is not working as expected?
-
1
You're thinking of inheritance in a reverse way: an instance of StreamNotFound is also an instance of NotFound, but an instance of a NotFound is not an instance of StreamNotFound. By the way: why on earth do you need those
.setPrototypeOf()
's?class
es set up their prototypes automatically. – FZs Commented Jan 31, 2022 at 17:40 - If you're viewing this question, you probably would be more interested in this similar question – Zach Saucier Commented Aug 13, 2023 at 21:55
2 Answers
Reset to default 6A subclass will always be an instanceof
itself and any of its parent classes. However, the reverse is not true: a parent class is not an instanceof
any of its subclasses.
In this example, StreamNotFound instanceof NotFound === true
. However, a parent class is explicitly not instanceof
any of its subclasses. Here, NotFound instanceof StreamNotFound === false
.
In your controller, you're throw
ing an instance of NotFound
, which will never be an instanceof StreamNotFound
, as it's further up in the prototype chain than its subclasses.
In the simplified example below, Bar
extends Foo
as a subclass, thus:
Foo instanceof Foo === true
Bar instanceof Foo === true
Bar instanceof Bar === true
Foo 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));
In my case, I had a root class of NodeCore
with two classes that extended that class: Leaf
and Choice
. I was attempting to use a type that allowed either subclass:
type Node = Leaf | Choice;
Then I was attempting to check the instanceof
that type:
if (node instanceof Node) { ... }
This doesn't work. But checking instanceof
of the original class does work:
if (node instanceof NodeCore) { ... }
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745138108a4613299.html
评论列表(0条)