-
Notifications
You must be signed in to change notification settings - Fork 113
Expand file tree
/
Copy patherrors.ts
More file actions
108 lines (102 loc) · 4.24 KB
/
Copy patherrors.ts
File metadata and controls
108 lines (102 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import type {
TransferErrorType,
TransferError,
TransferDetails,
} from 'telemetry/types';
import {
ERR_INSUFFICIENT_ALLOWANCE,
ERR_INSUFFICIENT_GAS,
ERR_TIMEOUT,
ERR_UNKNOWN,
ERR_USER_REJECTED,
ERR_AMOUNT_TOO_LARGE,
ERR_AMOUNT_TOO_SMALL,
ERR_RELAY_FAILED,
} from 'telemetry/types';
import { InsufficientFundsForGasError } from 'sdklegacy';
import { routes, amount as sdkAmount } from '@wormhole-foundation/sdk';
import { chainDisplayName, getGasToken, getTokenSymbol } from 'utils';
// TODO SDKV2
// attempt to capture errors using regex
export const INSUFFICIENT_ALLOWANCE_REGEX = /insufficient token allowance/im;
export const INSUFFICIENT_LAMPORTS_REGEX =
/insufficient lamports.*?(\d+).*?(\d+)/im;
export const SIMULATION_ACCOUNT_NOT_FOUND_REGEX =
/simulation failed:.*accountnotfound/i;
export const USER_REJECTED_REGEX = new RegExp(
'user rejected|rejected the request|rejected from user|user cancel|aborted by user|plugin closed|denied request signature',
'mi',
);
export const AMOUNT_IN_TOO_SMALL = new RegExp('AmountInTooSmall', 'm');
const INSUFFICIENT_FUNDS_FOR_GAS_ERROR =
'Insufficient funds for network fees. Please add more funds and try again';
export function interpretTransferError(
e: any,
transferDetails: TransferDetails,
): [string, TransferError] {
// Fall-back values
let uiErrorMessage = 'Error with transfer, please try again';
let internalErrorCode: TransferErrorType = ERR_UNKNOWN;
if (e.message) {
if (e instanceof routes.RelayFailedError) {
uiErrorMessage = e.message;
internalErrorCode = ERR_RELAY_FAILED;
} else if (INSUFFICIENT_ALLOWANCE_REGEX.test(e?.message)) {
uiErrorMessage = 'Error with transfer, please try again';
internalErrorCode = ERR_INSUFFICIENT_ALLOWANCE;
} else if (
e.name === 'TransactionExpiredTimeoutError' ||
e.name === 'TransactionExpiredBlockheightExceededError'
) {
// Solana timeout
uiErrorMessage = 'Transfer timed out, please try again';
internalErrorCode = ERR_TIMEOUT;
} else if (InsufficientFundsForGasError.MESSAGE_REGEX.test(e?.message)) {
uiErrorMessage = INSUFFICIENT_FUNDS_FOR_GAS_ERROR;
internalErrorCode = ERR_INSUFFICIENT_GAS;
} else if (USER_REJECTED_REGEX.test(e?.message)) {
uiErrorMessage = 'Transfer rejected in wallet, please try again';
internalErrorCode = ERR_USER_REJECTED;
} else if (AMOUNT_IN_TOO_SMALL.test(e?.message)) {
uiErrorMessage = 'Amount is too small for the selected route';
internalErrorCode = ERR_AMOUNT_TOO_SMALL;
} else if (
transferDetails.route.includes('CCTP') &&
/burn.*exceed/i.test(e?.toString())
) {
// As of this code being written the CCTP limit is 1,000,000 USDC in a single transfer
// It's possible Circle could change this in the future and we're not reading the limit
// from their contracts dynamically for now so we assume it's 1M and tell users that if
// their amount exceeded 1M
const assumedCircleLimit = 1_000_000;
const { amount } = transferDetails;
const limitString =
amount !== undefined && sdkAmount.whole(amount) > assumedCircleLimit
? ` of 1,000,000`
: '';
uiErrorMessage = `Amount exceeds Circle limit${limitString}. Please reduce transfer amount.`;
internalErrorCode = ERR_AMOUNT_TOO_LARGE;
} else if (
SIMULATION_ACCOUNT_NOT_FOUND_REGEX.test(e?.message) ||
INSUFFICIENT_LAMPORTS_REGEX.test(e?.message)
) {
const gasChain = transferDetails.fromChain;
try {
const gasToken = getGasToken(gasChain);
const gasSymbol = getTokenSymbol(gasToken);
const chainName = chainDisplayName(gasChain);
const chainSuffix = chainName ? ` on ${chainName}` : '';
uiErrorMessage = `Insufficient ${gasSymbol} for fees${chainSuffix}. Please add more ${gasSymbol} and try again`;
} catch {
uiErrorMessage = INSUFFICIENT_FUNDS_FOR_GAS_ERROR;
}
internalErrorCode = ERR_INSUFFICIENT_GAS;
}
}
return [uiErrorMessage, { type: internalErrorCode, original: e }];
}
export function maybeLogSdkError(e: any, prefix?: string) {
if (e instanceof Error && e.message.startsWith('No protocols registered for'))
return;
console.error(prefix ? `${prefix}: ${e}` : e);
}