add CustomError class

This will be used for throwing errors that can be caught and handled without having to parse the message.
This commit is contained in:
David Lechner
2022-05-20 11:13:55 -05:00
parent 8b6939a983
commit 348d6e90d9
2 changed files with 53 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 The Pybricks Authors
import { CustomError } from './customError';
// all subclasses should be declared like this:
type TestErrorName = 'Test';
class TestError extends CustomError<TestErrorName> {}
describe('CustomError', () => {
it('should work with instanceof', () => {
expect(new TestError('Test', 'test')).toBeInstanceOf(TestError);
});
it('should override name', () => {
expect(new TestError('Test', 'test')).toHaveProperty('name', 'Test');
});
it('should pass cause', () => {
const testCause = new Error('test cause');
expect(() => {
throw new TestError('Test', 'test', testCause);
}).toThrow({ name: 'Test', message: 'test', cause: testCause });
});
it('should serialize to something useful', () => {
expect(JSON.stringify(new TestError('Test', 'test'))).toBe(
'"[TestError: Test]"',
);
expect(`${new TestError('Test', 'test')}`).toBe('[TestError: Test]');
});
});
+18
View File
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 The Pybricks Authors
export class CustomError<T extends string> extends Error {
public constructor(name: T, message: string, cause?: Error) {
super(message, { cause });
this.name = name;
Object.setPrototypeOf(this, new.target.prototype);
}
public toString(): string {
return `[${this.constructor.name}: ${this.name}]`;
}
public toJSON(): string {
return this.toString();
}
}