src/utils: add ensureError() function

Typescript v4.4 no longer assumes that the error in catch is an Error
object [1]. This adds a helper function to ensure that caught errors
at least match the Error interface. If not, it creates a new Error
object with the value as the message.

[1]: https://devblogs.microsoft.com/typescript/announcing-typescript-4-4-beta/#using-unknown-in-catch-variables
This commit is contained in:
David Lechner
2021-08-30 13:06:01 -05:00
committed by David Lechner
parent 79db359398
commit e7d44ea9a9
8 changed files with 78 additions and 34 deletions
+11 -1
View File
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020 The Pybricks Authors
import { assert, defined, hex, maybe } from '.';
import { assert, defined, ensureError, hex, maybe } from '.';
test('assert', () => {
const assertTrue = jest.fn(() => assert(true, 'should not throw'));
@@ -34,3 +34,13 @@ test('hex', () => {
expect(hex(1, 4)).toBe('0x0001');
expect(hex(2, 8)).toBe('0x00000002');
});
test('ensureError', () => {
const err = new Error('test error');
expect(ensureError(err)).toBe(err);
const stringToErrorMessage = 'not an Error';
const stringToError = expect(ensureError(stringToErrorMessage));
stringToError.toHaveProperty('name', 'Error');
stringToError.toHaveProperty('message', stringToErrorMessage);
});
+24 -2
View File
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020 The Pybricks Authors
// Copyright (c) 2020-2021 The Pybricks Authors
/**
* Asserts that an assumption is true. This is used to detect programmer errors
@@ -29,7 +29,7 @@ export async function maybe<T>(promise: Promise<T>): Promise<Maybe<T>> {
try {
return [await promise];
} catch (err) {
return [undefined, err];
return [undefined, ensureError(err)];
}
}
@@ -41,3 +41,25 @@ export async function maybe<T>(promise: Promise<T>): Promise<Maybe<T>> {
export function hex(n: number, pad: number): string {
return `0x${n.toString(16).padStart(pad, '0')}`;
}
function isError(err: unknown): err is Error {
const maybeError = err as Error;
return (
maybeError !== undefined &&
typeof maybeError.name === 'string' &&
typeof maybeError.message === 'string'
);
}
export function ensureError(err: unknown): Error {
if (isError(err)) {
return err;
}
if (typeof err === 'string') {
return new Error(err);
}
return Error(String(err));
}