Skip to content

Commit

Permalink
Live 14437 sell fund improve exchange sdk code error (#94)
Browse files Browse the repository at this point in the history
* refactor: error handling

* refactor: rename errors

* test: fix swap tests

* refactor: remove comment
  • Loading branch information
sergiubreban authored Nov 18, 2024
1 parent 1b23f91 commit 9c25bf9
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 124 deletions.
91 changes: 91 additions & 0 deletions lib/src/error/ExchangeSdkError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
export class ExchangeBaseError extends Error {
cause: {
exchangeErrorCode: string;
[key: string]: string | Error | unknown | undefined;
};
message: string;
constructor(exchangeErrorCode = "exchange000", nestedError?: Error) {
super();
this.name = "ExchangeError";
// Support log for different error types.
this.cause = {
exchangeErrorCode,
...(nestedError?.constructor !== Object ||
nestedError?.constructor !== Array
? { message: `${nestedError}` }
: {}),
...nestedError,
};
this.message = nestedError?.message
? nestedError.message
: `${nestedError}`;
}
}

export class NonceStepError extends ExchangeBaseError {
constructor(nestedError?: Error) {
super("exchange001", nestedError);
this.name = "NonceStepError";
}
}

export class PayloadStepError extends ExchangeBaseError {
constructor(nestedError?: Error) {
super("exchange002", nestedError);
this.name = "PayloadStepError";
}
}

export class SignatureStepError extends ExchangeBaseError {
constructor(nestedError?: Error) {
super("exchange003", nestedError);
this.name = "SignatureStepError";
}
}
export class NotEnoughFunds extends ExchangeBaseError {
constructor() {
super("exchange004");
this.name = "NotEnoughFunds";
}
}

export class ListAccountError extends ExchangeBaseError {
constructor(nestedError?: Error) {
super("exchange005", nestedError);
this.name = "ListAccountError";
}
}

export class ListCurrencyError extends ExchangeBaseError {
constructor(nestedError?: Error) {
super("exchange006", nestedError);
this.name = "ListCurrencyError";
}
}

export class UnknownAccountError extends ExchangeBaseError {
constructor(nestedError?: Error) {
super("exchange007", nestedError);
this.name = "UnknownAccountError";
}
}

export class PayinExtraIdError extends ExchangeBaseError {
constructor(nestedError?: Error) {
super("exchange010", nestedError);
this.name = "PayinExtraIdError";
}
}
export type ExchangeSdkErrorType = ExchangeBaseError | NonceStepError | PayloadStepError | SignatureStepError | NotEnoughFunds | ListAccountError | ListCurrencyError | UnknownAccountError | PayinExtraIdError

export default {
ExchangeBaseError,
NonceStepError,
PayloadStepError,
SignatureStepError,
NotEnoughFunds,
ListAccountError,
ListCurrencyError,
UnknownAccountError,
PayinExtraIdError
}
10 changes: 10 additions & 0 deletions lib/src/error/LedgerLiveError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import ExchangeSdkError from "./ExchangeSdkError"

export class DrawerClosedError extends ExchangeSdkError.ExchangeBaseError {
handled: boolean;
constructor(nestedError?: Error) {
super("ll001", nestedError);
this.name = "DrawerClosedError";
this.handled = true;
}
}
29 changes: 10 additions & 19 deletions lib/src/error.ts → lib/src/error/SwapError.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export class ExchangeError extends Error {
export class SwapError extends Error {
cause: {
swapCode: string;
[key: string]: string | Error | unknown | undefined;
Expand All @@ -22,71 +22,62 @@ export class ExchangeError extends Error {
}
}

export class NonceStepError extends ExchangeError {
export class NonceStepError extends SwapError {
constructor(nestedError?: Error) {
super("swap001", nestedError);
this.name = "NonceStepError";
}
}

export class DrawerClosedError extends ExchangeError {
handled: boolean;
constructor(nestedError?: Error) {
super("ll001", nestedError);
this.name = "DrawerClosedError";
this.handled = true;
}
}

export class PayloadStepError extends ExchangeError {
export class PayloadStepError extends SwapError {
constructor(nestedError?: Error) {
super("swap002", nestedError);
this.name = "PayloadStepError";
}
}

export class SignatureStepError extends ExchangeError {
export class SignatureStepError extends SwapError {
constructor(nestedError?: Error) {
super("swap003", nestedError);
this.name = "SignatureStepError";
}
}
export class IgnoredSignatureStepError extends ExchangeError {
export class IgnoredSignatureStepError extends SwapError {
constructor(nestedError?: Error) {
super("swap003Ignored", nestedError);
this.name = "SignatureStepError";
}
}

export class NotEnoughFunds extends ExchangeError {
export class NotEnoughFunds extends SwapError {
constructor() {
super("swap004");
this.name = "NotEnoughFunds";
}
}

export class ListAccountError extends ExchangeError {
export class ListAccountError extends SwapError {
constructor(nestedError?: Error) {
super("swap005", nestedError);
this.name = "ListAccountError";
}
}

export class ListCurrencyError extends ExchangeError {
export class ListCurrencyError extends SwapError {
constructor(nestedError?: Error) {
super("swap006", nestedError);
this.name = "ListCurrencyError";
}
}

export class UnknownAccountError extends ExchangeError {
export class UnknownAccountError extends SwapError {
constructor(nestedError?: Error) {
super("swap007", nestedError);
this.name = "UnknownAccountError";
}
}

export class PayinExtraIdError extends ExchangeError {
export class PayinExtraIdError extends SwapError {
constructor(nestedError?: Error) {
super("swap010", nestedError);
this.name = "PayinExtraIdError";
Expand Down
9 changes: 2 additions & 7 deletions lib/src/handleErrors.ts → lib/src/error/handleErrors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { WalletAPIClient } from "@ledgerhq/wallet-api-client";
import { ExchangeError } from "./error";
import { SwapError } from "./SwapError";

/**
* Display error on LL if LL did not do it. Then throw error back to the live app in case they need to react to it
Expand Down Expand Up @@ -29,13 +29,8 @@ export function handleErrors(walletAPI: WalletAPIClient<any>, error: any) {
if (ignoredMessages.has(message) || ignoredErrorNames.has(cause.name)) {
throw { ...error, handled: true }; // retry ready
}

// Log and throw to Ledger Live if not ignored
if (
error instanceof ExchangeError &&
cause &&
cause.swapCode !== "swap003Ignored"
) {
if (error instanceof SwapError && cause && cause.swapCode !== "swap003Ignored") {
walletAPI.custom.exchange.throwExchangeErrorToLedgerLive({ error });
}

Expand Down
57 changes: 57 additions & 0 deletions lib/src/error/parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { IgnoredSignatureStepError, ListAccountError, ListCurrencyError, NonceStepError, NotEnoughFunds, PayinExtraIdError, PayloadStepError, SignatureStepError, UnknownAccountError } from './SwapError';
import ExchangeSdkError, { ExchangeSdkErrorType } from "./ExchangeSdkError"
import { DrawerClosedError } from "./LedgerLiveError"
import { FlowType } from '../sdk';

export enum StepError {
NONCE = 'NonceStepError',
PAYLOAD = 'PayloadStepError',
SIGNATURE = 'SignatureStepError',
IGNORED_SIGNATURE = 'IgnoredSignatureStepError',
CHECK_FUNDS = 'CheckFundsStepError',
LIST_ACCOUNT = 'ListAccountStepError',
LIST_CURRENCY = 'ListCurrencyStepError',
UNKNOWN_ACCOUNT = 'UnknownAccountStepError',
PAYIN_EXTRA_ID = 'PayinExtraIdStepError',
}

export const parseError = (flowType: FlowType, err: Error, step?: StepError) => {
if (err instanceof Error && err.name === "DrawerClosedError") {
return new DrawerClosedError(err)
}

switch (flowType) {
case 'generic':
case 'sell':
case 'card':
const genericError = step && GenericErrors[step]
return genericError ? new genericError(err) : err
case 'swap':
return step ? new SwapErrors[step](err) : err;
}
}
type ErrorConstructor = (new (err?: Error) => ExchangeSdkErrorType) | undefined;

const GenericErrors: Record<StepError, ErrorConstructor> = {
[StepError.NONCE]: ExchangeSdkError.NonceStepError,
[StepError.PAYLOAD]: ExchangeSdkError.PayloadStepError,
[StepError.SIGNATURE]: ExchangeSdkError.SignatureStepError,
[StepError.CHECK_FUNDS]: ExchangeSdkError.NotEnoughFunds,
[StepError.IGNORED_SIGNATURE]: undefined,
[StepError.LIST_ACCOUNT]: ExchangeSdkError.ListAccountError,
[StepError.LIST_CURRENCY]: ExchangeSdkError.ListCurrencyError,
[StepError.UNKNOWN_ACCOUNT]: ExchangeSdkError.UnknownAccountError,
[StepError.PAYIN_EXTRA_ID]: ExchangeSdkError.PayinExtraIdError
}

const SwapErrors: Record<StepError, new (err?: Error) => Error | undefined> = {
[StepError.NONCE]: NonceStepError,
[StepError.PAYLOAD]: PayloadStepError,
[StepError.SIGNATURE]: SignatureStepError,
[StepError.CHECK_FUNDS]: NotEnoughFunds,
[StepError.IGNORED_SIGNATURE]: IgnoredSignatureStepError,
[StepError.LIST_ACCOUNT]: ListAccountError,
[StepError.LIST_CURRENCY]: ListCurrencyError,
[StepError.UNKNOWN_ACCOUNT]: UnknownAccountError,
[StepError.PAYIN_EXTRA_ID]: PayinExtraIdError
}
6 changes: 3 additions & 3 deletions lib/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
export {
ExchangeError,
ExchangeBaseError,
ListAccountError,
ListCurrencyError,
NonceStepError,
DrawerClosedError,
NotEnoughFunds,
PayloadStepError,
SignatureStepError,
UnknownAccountError,
} from "./error";
} from "./error/ExchangeSdkError";
export { DrawerClosedError } from './error/LedgerLiveError';
export { QueryParams } from "./liveapp";
export { ExchangeSDK } from "./sdk";
export type { FeeStrategy } from "./sdk";
5 changes: 3 additions & 2 deletions lib/src/log.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ExchangeError } from "./error";
import { SwapError } from './error/SwapError';
import { ExchangeBaseError } from './error/ExchangeSdkError';

const style = "background: #7f0000; color: #fff";
const prefix = "[ExchangeSDK]";
Expand All @@ -16,7 +17,7 @@ export class Logger {
}
}

error(error: ExchangeError | Error) {
error(error: SwapError | ExchangeBaseError | Error) {
if (this.isActive) {
const errorParams = [
`%c${prefix} ERROR`,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from "./api";
import { ExchangeSDK, FeeStrategy } from "./sdk";
import { getCustomModule } from "./wallet-api";
import { CompleteExchangeError, IgnoredSignatureStepError, PayinExtraIdError, SignatureStepError } from "./error";
import { CompleteExchangeError, IgnoredSignatureStepError, PayinExtraIdError, SignatureStepError } from "./error/SwapError";

jest.mock("./api");

Expand Down
Loading

0 comments on commit 9c25bf9

Please sign in to comment.