Socket
Socket
Sign inDemoInstall

@ledgerhq/errors

Package Overview
Dependencies
0
Maintainers
21
Versions
221
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 6.16.0 to 6.16.1-nightly.0

LICENSE.txt

19

CHANGELOG.md
# @ledgerhq/errors
## 6.16.1-nightly.0
### Patch Changes
- [#5171](https://github.com/LedgerHQ/ledger-live/pull/5171) [`52a373273d`](https://github.com/LedgerHQ/ledger-live/commit/52a373273dee3b2cb5a3e8d2d4b05f90616d71a2) Thanks [@alexandremgo](https://github.com/alexandremgo)! - Feat: new abort timeout on opening transport and APDU exchange
On `@ledgerhq/hw-transport`
- `exchange` adding an optional `abortTimeoutMs` arg to its definition
- `send` taking an optional `abortTimeoutMs` and passing it to `exchange`
- Some documentation and tracing
On `@ledgerhq/react-native-hw-transport-ble`
- `open`: enabling optional timeout when opening a transport instance
- `exchange`: enabling optional timeout on APDU exchange, calling `cancelPendingOperations` on timeout
- `cancelPendingOperations`: using a `currentTransactionIds` array of transactions id for each `write`, we can try to abort completely pending writes
- More documentation + tracing + simple unit tests
## 6.16.0

@@ -4,0 +23,0 @@

25

lib-es/index.d.ts

@@ -60,3 +60,3 @@ import { serializeError, deserializeError, createCustomErrorClass, addCustomErrorDeserializer, LedgerErrorConstructor } from "./helpers";

}>;
export declare const LockedDeviceError: LedgerErrorConstructor<{
export declare const DeviceNeedsRestart: LedgerErrorConstructor<{
[key: string]: unknown;

@@ -271,2 +271,5 @@ }>;

}>;
export declare const TransportExchangeTimeoutError: LedgerErrorConstructor<{
[key: string]: unknown;
}>;
export declare const DeviceShouldStayInApp: LedgerErrorConstructor<{

@@ -350,2 +353,3 @@ [key: string]: unknown;

}>;
export type CustomErrorClassType = ReturnType<typeof createCustomErrorClass>;
/**

@@ -425,6 +429,19 @@ * Type of a Transport error used to represent all equivalent errors coming from all possible implementation of Transport

*/
export declare function TransportStatusError(statusCode: number): void;
export declare namespace TransportStatusError {
var prototype: Error;
export declare class TransportStatusError extends Error {
statusCode: number;
statusText: string;
/**
* @param statusCode The error status code coming from a Transport implementation
* @param options containing:
* - canBeMappedToChildError: enable the mapping of TransportStatusError to an error extending/inheriting from it
* . Ex: LockedDeviceError. Default to true.
*/
constructor(statusCode: number, { canBeMappedToChildError }?: {
canBeMappedToChildError?: boolean;
});
}
export declare class LockedDeviceError extends TransportStatusError {
constructor(message?: string);
}
export type TransportStatusErrorClassType = typeof TransportStatusError | typeof LockedDeviceError;
//# sourceMappingURL=index.d.ts.map

46

lib-es/index.js

@@ -22,3 +22,3 @@ import { serializeError, deserializeError, createCustomErrorClass, addCustomErrorDeserializer, } from "./helpers";

export const DeviceSocketNoBulkStatus = createCustomErrorClass("DeviceSocketNoBulkStatus");
export const LockedDeviceError = createCustomErrorClass("LockedDeviceError");
export const DeviceNeedsRestart = createCustomErrorClass("DeviceSocketNoBulkStatus");
export const UnresponsiveDeviceError = createCustomErrorClass("UnresponsiveDeviceError");

@@ -94,2 +94,3 @@ export const DisconnectedDevice = createCustomErrorClass("DisconnectedDevice");

export const TransactionHasBeenValidatedError = createCustomErrorClass("TransactionHasBeenValidatedError");
export const TransportExchangeTimeoutError = createCustomErrorClass("TransportExchangeTimeoutError");
export const DeviceShouldStayInApp = createCustomErrorClass("DeviceShouldStayInApp");

@@ -233,19 +234,34 @@ export const WebsocketConnectionError = createCustomErrorClass("WebsocketConnectionError");

*/
export function TransportStatusError(statusCode) {
const statusText = Object.keys(StatusCodes).find(k => StatusCodes[k] === statusCode) || "UNKNOWN_ERROR";
const smsg = getAltStatusMessage(statusCode) || statusText;
const statusCodeStr = statusCode.toString(16);
const message = `Ledger device: ${smsg} (0x${statusCodeStr})`;
// Maps to a LockedDeviceError
if (statusCode === StatusCodes.LOCKED_DEVICE) {
throw new LockedDeviceError(message);
export class TransportStatusError extends Error {
/**
* @param statusCode The error status code coming from a Transport implementation
* @param options containing:
* - canBeMappedToChildError: enable the mapping of TransportStatusError to an error extending/inheriting from it
* . Ex: LockedDeviceError. Default to true.
*/
constructor(statusCode, { canBeMappedToChildError = true } = {}) {
const statusText = Object.keys(StatusCodes).find(k => StatusCodes[k] === statusCode) || "UNKNOWN_ERROR";
const smsg = getAltStatusMessage(statusCode) || statusText;
const statusCodeStr = statusCode.toString(16);
const message = `Ledger device: ${smsg} (0x${statusCodeStr})`;
super(message);
this.name = "TransportStatusError";
this.statusCode = statusCode;
this.statusText = statusText;
// Maps to a LockedDeviceError
if (canBeMappedToChildError && statusCode === StatusCodes.LOCKED_DEVICE) {
return new LockedDeviceError(message);
}
}
this.name = "TransportStatusError";
this.message = message;
this.stack = new Error(message).stack;
this.statusCode = statusCode;
this.statusText = statusText;
}
TransportStatusError.prototype = new Error();
export class LockedDeviceError extends TransportStatusError {
constructor(message) {
super(StatusCodes.LOCKED_DEVICE, { canBeMappedToChildError: false });
if (message) {
this.message = message;
}
this.name = "LockedDeviceError";
}
}
addCustomErrorDeserializer("TransportStatusError", e => new TransportStatusError(e.statusCode));
//# sourceMappingURL=index.js.map

@@ -70,7 +70,22 @@ import { AmountRequired, CurrencyNotSupported, TransportStatusError, StatusCodes } from "./index";

});
test("transport status error contains message", () => {
const error = new TransportStatusError(StatusCodes.UNKNOWN_APDU);
expect(error.stack).toContain("Ledger device: UNKNOWN_APDU (0x6d02)");
describe("TransportStatusError", () => {
test("TransportStatusError contains the expected name, message, stack, status code and status message (non-regression)", () => {
const error = new TransportStatusError(StatusCodes.UNKNOWN_APDU);
console.log(`${JSON.stringify(error)}`);
expect(error.name).toEqual("TransportStatusError");
expect(error.message).toEqual("Ledger device: UNKNOWN_APDU (0x6d02)");
expect(error.stack).toContain("Ledger device: UNKNOWN_APDU (0x6d02)");
expect(error.statusText).toEqual("UNKNOWN_APDU");
expect(error.statusCode).toEqual(0x6d02);
});
test.only("TransportStatusError should be mapped to a LockedDeviceError on status code 0x5515", () => {
const error = new TransportStatusError(StatusCodes.LOCKED_DEVICE);
expect(error.name).toEqual("LockedDeviceError");
expect(error.message).toEqual("Ledger device: Locked device (0x5515)");
expect(error.stack).toContain("Ledger device: Locked device (0x5515)");
expect(error.statusText).toEqual("LOCKED_DEVICE");
expect(error.statusCode).toEqual(0x5515);
});
});
});
//# sourceMappingURL=index.test.js.map

@@ -60,3 +60,3 @@ import { serializeError, deserializeError, createCustomErrorClass, addCustomErrorDeserializer, LedgerErrorConstructor } from "./helpers";

}>;
export declare const LockedDeviceError: LedgerErrorConstructor<{
export declare const DeviceNeedsRestart: LedgerErrorConstructor<{
[key: string]: unknown;

@@ -271,2 +271,5 @@ }>;

}>;
export declare const TransportExchangeTimeoutError: LedgerErrorConstructor<{
[key: string]: unknown;
}>;
export declare const DeviceShouldStayInApp: LedgerErrorConstructor<{

@@ -350,2 +353,3 @@ [key: string]: unknown;

}>;
export type CustomErrorClassType = ReturnType<typeof createCustomErrorClass>;
/**

@@ -425,6 +429,19 @@ * Type of a Transport error used to represent all equivalent errors coming from all possible implementation of Transport

*/
export declare function TransportStatusError(statusCode: number): void;
export declare namespace TransportStatusError {
var prototype: Error;
export declare class TransportStatusError extends Error {
statusCode: number;
statusText: string;
/**
* @param statusCode The error status code coming from a Transport implementation
* @param options containing:
* - canBeMappedToChildError: enable the mapping of TransportStatusError to an error extending/inheriting from it
* . Ex: LockedDeviceError. Default to true.
*/
constructor(statusCode: number, { canBeMappedToChildError }?: {
canBeMappedToChildError?: boolean;
});
}
export declare class LockedDeviceError extends TransportStatusError {
constructor(message?: string);
}
export type TransportStatusErrorClassType = typeof TransportStatusError | typeof LockedDeviceError;
//# sourceMappingURL=index.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ManagerNotEnoughSpaceError = exports.ManagerFirmwareNotEnoughSpaceError = exports.ManagerDeviceLockedError = exports.ManagerAppDepUninstallRequired = exports.ManagerAppDepInstallRequired = exports.ManagerAppRelyOnBTCError = exports.ManagerAppAlreadyInstalledError = exports.LedgerAPINotAvailable = exports.LedgerAPIErrorWithMessage = exports.LedgerAPIError = exports.UnknownMCU = exports.LatestMCUInstalledError = exports.InvalidAddressBecauseDestinationIsAlsoSource = exports.InvalidNonce = exports.InvalidAddress = exports.InvalidXRPTag = exports.HardResetFail = exports.FirmwareNotRecognized = exports.FeeEstimationFailed = exports.EthAppPleaseEnableContractData = exports.EnpointConfigError = exports.DeviceOnboardingStatePollingError = exports.DeviceExtractOnboardingStateError = exports.DisconnectedDeviceDuringOperation = exports.DisconnectedDevice = exports.UnresponsiveDeviceError = exports.LockedDeviceError = exports.DeviceSocketNoBulkStatus = exports.DeviceSocketFail = exports.DeviceNameInvalid = exports.DeviceHalted = exports.DeviceInOSUExpected = exports.DeviceOnDashboardUnexpected = exports.DeviceOnDashboardExpected = exports.DeviceNotGenuineError = exports.DeviceGenuineSocketEarlyClose = exports.DeviceAppVerifyNotSupported = exports.CurrencyNotSupported = exports.ClaimRewardsFeesWarning = exports.CashAddrNotSupported = exports.CantOpenDevice = exports.BtcUnmatchedApp = exports.BluetoothRequired = exports.AmountRequired = exports.AccountNotSupported = exports.AccountNameRequiredError = exports.addCustomErrorDeserializer = exports.createCustomErrorClass = exports.deserializeError = exports.serializeError = void 0;
exports.CantScanQRCode = exports.ETHAddressNonEIP = exports.WrongAppForCurrency = exports.WrongDeviceForAccount = exports.WebsocketConnectionFailed = exports.WebsocketConnectionError = exports.DeviceShouldStayInApp = exports.TransactionHasBeenValidatedError = exports.TransportWebUSBGestureRequired = exports.TransportRaceCondition = exports.TransportInterfaceNotAvailable = exports.TransportOpenUserCancelled = exports.ExpertModeRequired = exports.UserRefusedOnDevice = exports.UserRefusedAllowManager = exports.UserRefusedFirmwareUpdate = exports.UserRefusedAddress = exports.UserRefusedDeviceNameChange = exports.UpdateYourApp = exports.UpdateIncorrectSig = exports.UpdateIncorrectHash = exports.UpdateFetchFileFail = exports.UnavailableTezosOriginatedAccountSend = exports.UnavailableTezosOriginatedAccountReceive = exports.RecipientRequired = exports.MCUNotGenuineToDashboard = exports.UnexpectedBootloader = exports.TimeoutTagged = exports.RecommendUndelegation = exports.RecommendSubAccountsToEmpty = exports.PasswordIncorrectError = exports.PasswordsDontMatchError = exports.MaxFeeTooLow = exports.PriorityFeeHigherThanMaxFee = exports.PriorityFeeTooHigh = exports.PriorityFeeTooLow = exports.GasLessThanEstimate = exports.NotSupportedLegacyAddress = exports.NotEnoughGasSwap = exports.NotEnoughGas = exports.NoAccessToCamera = exports.NotEnoughBalanceBecauseDestinationNotCreated = exports.NotEnoughSpendableBalance = exports.NotEnoughBalanceInParentAccount = exports.NotEnoughBalanceToDelegate = exports.NotEnoughBalance = exports.NoAddressesFound = exports.NetworkError = exports.NetworkDown = exports.ManagerUninstallBTCDep = void 0;
exports.TransportStatusError = exports.getAltStatusMessage = exports.StatusCodes = exports.TransportError = exports.HwTransportError = exports.HwTransportErrorType = exports.DBNotReset = exports.DBWrongPassword = exports.NoDBPathGiven = exports.LanguageNotFound = exports.DustLimit = exports.OpReturnDataSizeLimit = exports.ReplacementTransactionUnderpriced = exports.FirmwareOrAppUpdateRequired = exports.LedgerAPI5xx = exports.LedgerAPI4xx = exports.GenuineCheckFailed = exports.PeerRemovedPairing = exports.PairingFailed = exports.SyncError = exports.PendingOperation = exports.FeeTooHigh = exports.FeeRequired = exports.FeeNotLoadedSwap = exports.FeeNotLoaded = void 0;
exports.ManagerNotEnoughSpaceError = exports.ManagerFirmwareNotEnoughSpaceError = exports.ManagerDeviceLockedError = exports.ManagerAppDepUninstallRequired = exports.ManagerAppDepInstallRequired = exports.ManagerAppRelyOnBTCError = exports.ManagerAppAlreadyInstalledError = exports.LedgerAPINotAvailable = exports.LedgerAPIErrorWithMessage = exports.LedgerAPIError = exports.UnknownMCU = exports.LatestMCUInstalledError = exports.InvalidAddressBecauseDestinationIsAlsoSource = exports.InvalidNonce = exports.InvalidAddress = exports.InvalidXRPTag = exports.HardResetFail = exports.FirmwareNotRecognized = exports.FeeEstimationFailed = exports.EthAppPleaseEnableContractData = exports.EnpointConfigError = exports.DeviceOnboardingStatePollingError = exports.DeviceExtractOnboardingStateError = exports.DisconnectedDeviceDuringOperation = exports.DisconnectedDevice = exports.UnresponsiveDeviceError = exports.DeviceNeedsRestart = exports.DeviceSocketNoBulkStatus = exports.DeviceSocketFail = exports.DeviceNameInvalid = exports.DeviceHalted = exports.DeviceInOSUExpected = exports.DeviceOnDashboardUnexpected = exports.DeviceOnDashboardExpected = exports.DeviceNotGenuineError = exports.DeviceGenuineSocketEarlyClose = exports.DeviceAppVerifyNotSupported = exports.CurrencyNotSupported = exports.ClaimRewardsFeesWarning = exports.CashAddrNotSupported = exports.CantOpenDevice = exports.BtcUnmatchedApp = exports.BluetoothRequired = exports.AmountRequired = exports.AccountNotSupported = exports.AccountNameRequiredError = exports.addCustomErrorDeserializer = exports.createCustomErrorClass = exports.deserializeError = exports.serializeError = void 0;
exports.ETHAddressNonEIP = exports.WrongAppForCurrency = exports.WrongDeviceForAccount = exports.WebsocketConnectionFailed = exports.WebsocketConnectionError = exports.DeviceShouldStayInApp = exports.TransportExchangeTimeoutError = exports.TransactionHasBeenValidatedError = exports.TransportWebUSBGestureRequired = exports.TransportRaceCondition = exports.TransportInterfaceNotAvailable = exports.TransportOpenUserCancelled = exports.ExpertModeRequired = exports.UserRefusedOnDevice = exports.UserRefusedAllowManager = exports.UserRefusedFirmwareUpdate = exports.UserRefusedAddress = exports.UserRefusedDeviceNameChange = exports.UpdateYourApp = exports.UpdateIncorrectSig = exports.UpdateIncorrectHash = exports.UpdateFetchFileFail = exports.UnavailableTezosOriginatedAccountSend = exports.UnavailableTezosOriginatedAccountReceive = exports.RecipientRequired = exports.MCUNotGenuineToDashboard = exports.UnexpectedBootloader = exports.TimeoutTagged = exports.RecommendUndelegation = exports.RecommendSubAccountsToEmpty = exports.PasswordIncorrectError = exports.PasswordsDontMatchError = exports.MaxFeeTooLow = exports.PriorityFeeHigherThanMaxFee = exports.PriorityFeeTooHigh = exports.PriorityFeeTooLow = exports.GasLessThanEstimate = exports.NotSupportedLegacyAddress = exports.NotEnoughGasSwap = exports.NotEnoughGas = exports.NoAccessToCamera = exports.NotEnoughBalanceBecauseDestinationNotCreated = exports.NotEnoughSpendableBalance = exports.NotEnoughBalanceInParentAccount = exports.NotEnoughBalanceToDelegate = exports.NotEnoughBalance = exports.NoAddressesFound = exports.NetworkError = exports.NetworkDown = exports.ManagerUninstallBTCDep = void 0;
exports.LockedDeviceError = exports.TransportStatusError = exports.getAltStatusMessage = exports.StatusCodes = exports.TransportError = exports.HwTransportError = exports.HwTransportErrorType = exports.DBNotReset = exports.DBWrongPassword = exports.NoDBPathGiven = exports.LanguageNotFound = exports.DustLimit = exports.OpReturnDataSizeLimit = exports.ReplacementTransactionUnderpriced = exports.FirmwareOrAppUpdateRequired = exports.LedgerAPI5xx = exports.LedgerAPI4xx = exports.GenuineCheckFailed = exports.PeerRemovedPairing = exports.PairingFailed = exports.SyncError = exports.PendingOperation = exports.FeeTooHigh = exports.FeeRequired = exports.FeeNotLoadedSwap = exports.FeeNotLoaded = exports.CantScanQRCode = void 0;
const helpers_1 = require("./helpers");

@@ -30,3 +30,3 @@ Object.defineProperty(exports, "serializeError", { enumerable: true, get: function () { return helpers_1.serializeError; } });

exports.DeviceSocketNoBulkStatus = (0, helpers_1.createCustomErrorClass)("DeviceSocketNoBulkStatus");
exports.LockedDeviceError = (0, helpers_1.createCustomErrorClass)("LockedDeviceError");
exports.DeviceNeedsRestart = (0, helpers_1.createCustomErrorClass)("DeviceSocketNoBulkStatus");
exports.UnresponsiveDeviceError = (0, helpers_1.createCustomErrorClass)("UnresponsiveDeviceError");

@@ -102,2 +102,3 @@ exports.DisconnectedDevice = (0, helpers_1.createCustomErrorClass)("DisconnectedDevice");

exports.TransactionHasBeenValidatedError = (0, helpers_1.createCustomErrorClass)("TransactionHasBeenValidatedError");
exports.TransportExchangeTimeoutError = (0, helpers_1.createCustomErrorClass)("TransportExchangeTimeoutError");
exports.DeviceShouldStayInApp = (0, helpers_1.createCustomErrorClass)("DeviceShouldStayInApp");

@@ -244,20 +245,36 @@ exports.WebsocketConnectionError = (0, helpers_1.createCustomErrorClass)("WebsocketConnectionError");

*/
function TransportStatusError(statusCode) {
const statusText = Object.keys(exports.StatusCodes).find(k => exports.StatusCodes[k] === statusCode) || "UNKNOWN_ERROR";
const smsg = getAltStatusMessage(statusCode) || statusText;
const statusCodeStr = statusCode.toString(16);
const message = `Ledger device: ${smsg} (0x${statusCodeStr})`;
// Maps to a LockedDeviceError
if (statusCode === exports.StatusCodes.LOCKED_DEVICE) {
throw new exports.LockedDeviceError(message);
class TransportStatusError extends Error {
/**
* @param statusCode The error status code coming from a Transport implementation
* @param options containing:
* - canBeMappedToChildError: enable the mapping of TransportStatusError to an error extending/inheriting from it
* . Ex: LockedDeviceError. Default to true.
*/
constructor(statusCode, { canBeMappedToChildError = true } = {}) {
const statusText = Object.keys(exports.StatusCodes).find(k => exports.StatusCodes[k] === statusCode) || "UNKNOWN_ERROR";
const smsg = getAltStatusMessage(statusCode) || statusText;
const statusCodeStr = statusCode.toString(16);
const message = `Ledger device: ${smsg} (0x${statusCodeStr})`;
super(message);
this.name = "TransportStatusError";
this.statusCode = statusCode;
this.statusText = statusText;
// Maps to a LockedDeviceError
if (canBeMappedToChildError && statusCode === exports.StatusCodes.LOCKED_DEVICE) {
return new LockedDeviceError(message);
}
}
this.name = "TransportStatusError";
this.message = message;
this.stack = new Error(message).stack;
this.statusCode = statusCode;
this.statusText = statusText;
}
exports.TransportStatusError = TransportStatusError;
TransportStatusError.prototype = new Error();
class LockedDeviceError extends TransportStatusError {
constructor(message) {
super(exports.StatusCodes.LOCKED_DEVICE, { canBeMappedToChildError: false });
if (message) {
this.message = message;
}
this.name = "LockedDeviceError";
}
}
exports.LockedDeviceError = LockedDeviceError;
(0, helpers_1.addCustomErrorDeserializer)("TransportStatusError", e => new TransportStatusError(e.statusCode));
//# sourceMappingURL=index.js.map

@@ -72,7 +72,22 @@ "use strict";

});
test("transport status error contains message", () => {
const error = new index_1.TransportStatusError(index_1.StatusCodes.UNKNOWN_APDU);
expect(error.stack).toContain("Ledger device: UNKNOWN_APDU (0x6d02)");
describe("TransportStatusError", () => {
test("TransportStatusError contains the expected name, message, stack, status code and status message (non-regression)", () => {
const error = new index_1.TransportStatusError(index_1.StatusCodes.UNKNOWN_APDU);
console.log(`${JSON.stringify(error)}`);
expect(error.name).toEqual("TransportStatusError");
expect(error.message).toEqual("Ledger device: UNKNOWN_APDU (0x6d02)");
expect(error.stack).toContain("Ledger device: UNKNOWN_APDU (0x6d02)");
expect(error.statusText).toEqual("UNKNOWN_APDU");
expect(error.statusCode).toEqual(0x6d02);
});
test.only("TransportStatusError should be mapped to a LockedDeviceError on status code 0x5515", () => {
const error = new index_1.TransportStatusError(index_1.StatusCodes.LOCKED_DEVICE);
expect(error.name).toEqual("LockedDeviceError");
expect(error.message).toEqual("Ledger device: Locked device (0x5515)");
expect(error.stack).toContain("Ledger device: Locked device (0x5515)");
expect(error.statusText).toEqual("LOCKED_DEVICE");
expect(error.statusCode).toEqual(0x5515);
});
});
});
//# sourceMappingURL=index.test.js.map
{
"name": "@ledgerhq/errors",
"version": "6.16.0",
"version": "6.16.1-nightly.0",
"description": "Ledger common errors",

@@ -5,0 +5,0 @@ "keywords": [

@@ -54,2 +54,4 @@ <img src="https://user-images.githubusercontent.com/4631227/191834116-59cf590e-25cc-4956-ae5c-812ea464f324.png" height="100" />

**Extends Error**
Error thrown when a device returned a non success status.

@@ -60,4 +62,6 @@ the error.statusCode is one of the `StatusCodes` exported by this library.

* `statusCode` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)**&#x20;
* `statusCode` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The error status code coming from a Transport implementation
* `options` **{canBeMappedToChildError: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?}** containing:* canBeMappedToChildError: enable the mapping of TransportStatusError to an error extending/inheriting from it
. Ex: LockedDeviceError. Default to true. (optional, default `{}`)
Returns **void**&#x20;
* `options.canBeMappedToChildError` (optional, default `true`)

@@ -76,6 +76,25 @@ import { AmountRequired, CurrencyNotSupported, TransportStatusError, StatusCodes } from "./index";

test("transport status error contains message", () => {
const error: Error = new TransportStatusError(StatusCodes.UNKNOWN_APDU);
expect(error.stack).toContain("Ledger device: UNKNOWN_APDU (0x6d02)");
describe("TransportStatusError", () => {
test("TransportStatusError contains the expected name, message, stack, status code and status message (non-regression)", () => {
const error = new TransportStatusError(StatusCodes.UNKNOWN_APDU);
console.log(`${JSON.stringify(error)}`);
expect(error.name).toEqual("TransportStatusError");
expect(error.message).toEqual("Ledger device: UNKNOWN_APDU (0x6d02)");
expect(error.stack).toContain("Ledger device: UNKNOWN_APDU (0x6d02)");
expect(error.statusText).toEqual("UNKNOWN_APDU");
expect(error.statusCode).toEqual(0x6d02);
});
test.only("TransportStatusError should be mapped to a LockedDeviceError on status code 0x5515", () => {
const error = new TransportStatusError(StatusCodes.LOCKED_DEVICE);
expect(error.name).toEqual("LockedDeviceError");
expect(error.message).toEqual("Ledger device: Locked device (0x5515)");
expect(error.stack).toContain("Ledger device: Locked device (0x5515)");
expect(error.statusText).toEqual("LOCKED_DEVICE");
expect(error.statusCode).toEqual(0x5515);
});
});
});

@@ -35,3 +35,3 @@ import {

export const DeviceSocketNoBulkStatus = createCustomErrorClass("DeviceSocketNoBulkStatus");
export const LockedDeviceError = createCustomErrorClass("LockedDeviceError");
export const DeviceNeedsRestart = createCustomErrorClass("DeviceSocketNoBulkStatus");
export const UnresponsiveDeviceError = createCustomErrorClass("UnresponsiveDeviceError");

@@ -135,2 +135,5 @@ export const DisconnectedDevice = createCustomErrorClass("DisconnectedDevice");

);
export const TransportExchangeTimeoutError = createCustomErrorClass(
"TransportExchangeTimeoutError",
);
export const DeviceShouldStayInApp = createCustomErrorClass("DeviceShouldStayInApp");

@@ -174,2 +177,5 @@ export const WebsocketConnectionError = createCustomErrorClass("WebsocketConnectionError");

// Represents the type of all the classes created with createCustomErrorClass
export type CustomErrorClassType = ReturnType<typeof createCustomErrorClass>;
/**

@@ -292,22 +298,48 @@ * Type of a Transport error used to represent all equivalent errors coming from all possible implementation of Transport

*/
export function TransportStatusError(statusCode: number): void {
const statusText =
Object.keys(StatusCodes).find(k => StatusCodes[k] === statusCode) || "UNKNOWN_ERROR";
const smsg = getAltStatusMessage(statusCode) || statusText;
const statusCodeStr = statusCode.toString(16);
const message = `Ledger device: ${smsg} (0x${statusCodeStr})`;
export class TransportStatusError extends Error {
statusCode: number;
statusText: string;
// Maps to a LockedDeviceError
if (statusCode === StatusCodes.LOCKED_DEVICE) {
throw new LockedDeviceError(message);
/**
* @param statusCode The error status code coming from a Transport implementation
* @param options containing:
* - canBeMappedToChildError: enable the mapping of TransportStatusError to an error extending/inheriting from it
* . Ex: LockedDeviceError. Default to true.
*/
constructor(
statusCode: number,
{ canBeMappedToChildError = true }: { canBeMappedToChildError?: boolean } = {},
) {
const statusText =
Object.keys(StatusCodes).find(k => StatusCodes[k] === statusCode) || "UNKNOWN_ERROR";
const smsg = getAltStatusMessage(statusCode) || statusText;
const statusCodeStr = statusCode.toString(16);
const message = `Ledger device: ${smsg} (0x${statusCodeStr})`;
super(message);
this.name = "TransportStatusError";
this.statusCode = statusCode;
this.statusText = statusText;
// Maps to a LockedDeviceError
if (canBeMappedToChildError && statusCode === StatusCodes.LOCKED_DEVICE) {
return new LockedDeviceError(message);
}
}
}
this.name = "TransportStatusError";
this.message = message;
this.stack = new Error(message).stack;
this.statusCode = statusCode;
this.statusText = statusText;
export class LockedDeviceError extends TransportStatusError {
constructor(message?: string) {
super(StatusCodes.LOCKED_DEVICE, { canBeMappedToChildError: false });
if (message) {
this.message = message;
}
this.name = "LockedDeviceError";
}
}
TransportStatusError.prototype = new Error();
// Represents the type of the class TransportStatusError and its children
export type TransportStatusErrorClassType = typeof TransportStatusError | typeof LockedDeviceError;
addCustomErrorDeserializer("TransportStatusError", e => new TransportStatusError(e.statusCode));

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc