make bootloader failure reasons more strongly typed

This way we don't have to do extra null checks elsewhere.
This commit is contained in:
David Lechner
2021-01-21 12:37:29 -06:00
parent 904de515c0
commit 2659c064fa
3 changed files with 47 additions and 16 deletions
+46 -9
View File
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020 The Pybricks Authors
// Copyright (c) 2020-2021 The Pybricks Authors
import { Action } from 'redux';
import {
@@ -64,26 +64,63 @@ export function didConnect(): BootloaderConnectionDidConnectAction {
* Possible reasons a device could fail to connect.
*/
export enum BootloaderConnectionFailureReason {
/** The reason is not known */
Unknown = 'unknown',
/** The connection was canceled */
Canceled = 'canceled',
/** Web Bluetooth is not available */
NoWebBluetooth = 'no-web-bluetooth',
/** Connected but failed to find the bootloader GATT service */
GattServiceNotFound = 'gatt-service-not-found',
/** The connection was canceled */
Canceled = 'canceled',
/** The reason is not known */
Unknown = 'unknown',
}
export type BootloaderConnectionDidFailToConnectAction = Action<BootloaderConnectionActionType.DidFailToConnect> & {
reason: BootloaderConnectionFailureReason;
err?: Error;
type Reason<T extends BootloaderConnectionFailureReason> = {
reason: T;
};
export type BootloaderConnectionFailToConnectNoWebBluetoothReason = Reason<BootloaderConnectionFailureReason.NoWebBluetooth>;
export type BootloaderConnectionFailToConnectGattServiceNotFoundReason = Reason<BootloaderConnectionFailureReason.GattServiceNotFound>;
export type BootloaderConnectionFailToConnectCanceledReason = Reason<BootloaderConnectionFailureReason.Canceled>;
export type BootloaderConnectionFailToConnectUnknownReason = Reason<BootloaderConnectionFailureReason.Unknown> & {
err: Error;
};
export type BootloaderConnectionDidFailToConnectReason =
| BootloaderConnectionFailToConnectNoWebBluetoothReason
| BootloaderConnectionFailToConnectGattServiceNotFoundReason
| BootloaderConnectionFailToConnectCanceledReason
| BootloaderConnectionFailToConnectUnknownReason;
export type BootloaderConnectionDidFailToConnectAction = Action<BootloaderConnectionActionType.DidFailToConnect> &
BootloaderConnectionDidFailToConnectReason;
export function didFailToConnect(
reason: Exclude<
BootloaderConnectionFailureReason,
BootloaderConnectionFailureReason.Unknown
>,
): BootloaderConnectionDidFailToConnectAction;
export function didFailToConnect(
reason: BootloaderConnectionFailureReason.Unknown,
err: Error,
): BootloaderConnectionDidFailToConnectAction;
export function didFailToConnect(
reason: BootloaderConnectionFailureReason,
err?: Error,
): BootloaderConnectionDidFailToConnectAction {
return { type: BootloaderConnectionActionType.DidFailToConnect, reason, err };
if (reason === BootloaderConnectionFailureReason.Unknown) {
return <BootloaderConnectionDidFailToConnectAction>{
type: BootloaderConnectionActionType.DidFailToConnect,
reason,
err,
};
}
return { type: BootloaderConnectionActionType.DidFailToConnect, reason };
}
export type BootloaderConnectionDidErrorAction = Action<BootloaderConnectionActionType.DidError> & {
+1 -5
View File
@@ -49,12 +49,8 @@ test('bleDataDidFailToWrite', async () => {
test('bootloaderDidFailToConnect', async () => {
const saga = new AsyncSaga(errorLog);
console.debug = jest.fn();
saga.put(didFailToConnect(BootloaderConnectionFailureReason.Canceled));
expect(console.debug).toHaveBeenCalledTimes(1);
console.error = jest.fn();
saga.put(didFailToConnect(BootloaderConnectionFailureReason.Unknown));
saga.put(didFailToConnect(BootloaderConnectionFailureReason.Unknown, <Error>{}));
expect(console.error).toHaveBeenCalledTimes(1);
await saga.end();
-2
View File
@@ -31,8 +31,6 @@ function bootloaderDidFailToConnect(
): void {
if (action.reason === BootloaderConnectionFailureReason.Unknown) {
console.error(action.err);
} else {
console.debug(action.err);
}
}