@solana/errors 8.6.0 → 8.7.0-canary-20261102161207
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +16 -4
- package/dist/index.browser.cjs +23 -7
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.mjs +22 -8
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.native.mjs +22 -8
- package/dist/index.native.mjs.map +1 -1
- package/dist/index.node.cjs +23 -7
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +22 -8
- package/dist/index.node.mjs.map +1 -1
- package/dist/types/codes.d.ts +13 -2
- package/dist/types/codes.d.ts.map +1 -1
- package/dist/types/context.d.ts +4 -1
- package/dist/types/context.d.ts.map +1 -1
- package/dist/types/json-rpc-error.d.ts.map +1 -1
- package/dist/types/message-formatter.d.ts.map +1 -1
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/simulation-errors.d.ts +38 -4
- package/dist/types/simulation-errors.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli.ts +8 -3
- package/src/codes.ts +16 -3
- package/src/context.ts +4 -0
- package/src/json-rpc-error.ts +8 -1
- package/src/message-formatter.ts +9 -0
- package/src/messages.ts +2 -0
- package/src/simulation-errors.ts +50 -12
package/src/json-rpc-error.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET,
|
|
11
11
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_FILTER_TRANSACTION_NOT_FOUND,
|
|
12
12
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX,
|
|
13
|
+
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LEADER_SCHEDULE_IDENTITY_NOT_FOUND,
|
|
13
14
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED,
|
|
14
15
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,
|
|
15
16
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED,
|
|
@@ -130,6 +131,7 @@ export function getSolanaErrorFromJsonRpcError(putativeErrorResponse: unknown):
|
|
|
130
131
|
case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET:
|
|
131
132
|
case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_FILTER_TRANSACTION_NOT_FOUND:
|
|
132
133
|
case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX:
|
|
134
|
+
case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LEADER_SCHEDULE_IDENTITY_NOT_FOUND:
|
|
133
135
|
case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED:
|
|
134
136
|
case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED:
|
|
135
137
|
case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE:
|
|
@@ -141,8 +143,13 @@ export function getSolanaErrorFromJsonRpcError(putativeErrorResponse: unknown):
|
|
|
141
143
|
errorContext = { __serverMessage: message };
|
|
142
144
|
break;
|
|
143
145
|
default:
|
|
144
|
-
if (typeof data === 'object' && !Array.isArray(data)) {
|
|
146
|
+
if (typeof data === 'object' && data !== null && !Array.isArray(data)) {
|
|
145
147
|
errorContext = data;
|
|
148
|
+
} else {
|
|
149
|
+
// No structured data. Keep the server message so it's not lost; this
|
|
150
|
+
// matters most for codes that this version of the library doesn't know
|
|
151
|
+
// about (eg. one introduced by a newer RPC server).
|
|
152
|
+
errorContext = { __serverMessage: message };
|
|
146
153
|
}
|
|
147
154
|
}
|
|
148
155
|
out = new SolanaError(code as SolanaErrorCode, errorContext as SolanaErrorContext[SolanaErrorCode]);
|
package/src/message-formatter.ts
CHANGED
|
@@ -20,6 +20,15 @@ export function getHumanReadableErrorMessage<TErrorCode extends SolanaErrorCode>
|
|
|
20
20
|
code: TErrorCode,
|
|
21
21
|
context: object = {},
|
|
22
22
|
): string {
|
|
23
|
+
if (!(code in SolanaErrorMessages)) {
|
|
24
|
+
// A code that this version of the library has no message for, such as a JSON-RPC error
|
|
25
|
+
// code introduced by a newer RPC server. Report the code rather than throwing, along with
|
|
26
|
+
// the server's own message if one was captured.
|
|
27
|
+
return '__serverMessage' in context
|
|
28
|
+
? // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
29
|
+
`Unknown Solana error code: ${code} (${context.__serverMessage})`
|
|
30
|
+
: `Unknown Solana error code: ${code}`;
|
|
31
|
+
}
|
|
23
32
|
const messageFormatString = SolanaErrorMessages[code];
|
|
24
33
|
if (messageFormatString.length === 0) {
|
|
25
34
|
return '';
|
package/src/messages.ts
CHANGED
|
@@ -168,6 +168,7 @@ import {
|
|
|
168
168
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_EPOCH_REWARDS_PERIOD_ACTIVE,
|
|
169
169
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_FILTER_TRANSACTION_NOT_FOUND,
|
|
170
170
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX,
|
|
171
|
+
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LEADER_SCHEDULE_IDENTITY_NOT_FOUND,
|
|
171
172
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED,
|
|
172
173
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_UNREACHABLE,
|
|
173
174
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,
|
|
@@ -618,6 +619,7 @@ export const SolanaErrorMessages: Readonly<{
|
|
|
618
619
|
'Epoch rewards period still active at slot $slot',
|
|
619
620
|
[SOLANA_ERROR__JSON_RPC__SERVER_ERROR_FILTER_TRANSACTION_NOT_FOUND]: '$__serverMessage',
|
|
620
621
|
[SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX]: '$__serverMessage',
|
|
622
|
+
[SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LEADER_SCHEDULE_IDENTITY_NOT_FOUND]: '$__serverMessage',
|
|
621
623
|
[SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED]: '$__serverMessage',
|
|
622
624
|
[SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_UNREACHABLE]:
|
|
623
625
|
'Failed to query long-term storage; please try again',
|
package/src/simulation-errors.ts
CHANGED
|
@@ -2,9 +2,55 @@ import {
|
|
|
2
2
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,
|
|
3
3
|
SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,
|
|
4
4
|
SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_RESOURCE_LIMITS,
|
|
5
|
-
|
|
5
|
+
SolanaErrorCodeWithSimulationResult,
|
|
6
6
|
} from './codes';
|
|
7
|
-
import { isSolanaError } from './error';
|
|
7
|
+
import { isSolanaError, SolanaError } from './error';
|
|
8
|
+
|
|
9
|
+
// Typed as a record so that the compiler fails whenever this list and the
|
|
10
|
+
// `SolanaErrorCodeWithSimulationResult` union drift apart, in either direction.
|
|
11
|
+
const SIMULATION_ERROR_CODES: Readonly<Record<SolanaErrorCodeWithSimulationResult, true>> = {
|
|
12
|
+
[SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE]: true,
|
|
13
|
+
[SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT]: true,
|
|
14
|
+
[SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_RESOURCE_LIMITS]: true,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A type guard that returns `true` if the input is a {@link SolanaError} thrown because a
|
|
19
|
+
* transaction simulation failed.
|
|
20
|
+
*
|
|
21
|
+
* When this returns `true`, TypeScript will refine the error's
|
|
22
|
+
* {@link SolanaError#context | `context`} to the simulation result (eg. `logs` and
|
|
23
|
+
* `unitsConsumed`). The underlying transaction error, if any, is available as the error's `cause`.
|
|
24
|
+
*
|
|
25
|
+
* The following error codes are considered simulation errors:
|
|
26
|
+
* - {@link SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE}
|
|
27
|
+
* - {@link SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT}
|
|
28
|
+
* - {@link SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_RESOURCE_LIMITS}
|
|
29
|
+
*
|
|
30
|
+
* @param e - The value to check.
|
|
31
|
+
* @return `true` if the input is a simulation error, `false` otherwise.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* Reading the simulation logs of a failed transaction.
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { isSimulationError } from '@solana/errors';
|
|
37
|
+
*
|
|
38
|
+
* try {
|
|
39
|
+
* await sendTransaction(signedTransaction);
|
|
40
|
+
* } catch (e) {
|
|
41
|
+
* if (isSimulationError(e)) {
|
|
42
|
+
* console.log('Simulation failed due to:', e.cause);
|
|
43
|
+
* console.log('Simulation logs:', e.context.logs);
|
|
44
|
+
* }
|
|
45
|
+
* throw e;
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @see {@link unwrapSimulationError}
|
|
50
|
+
*/
|
|
51
|
+
export function isSimulationError(e: unknown): e is SolanaError<SolanaErrorCodeWithSimulationResult> {
|
|
52
|
+
return isSolanaError(e) && e.context.__code in SIMULATION_ERROR_CODES;
|
|
53
|
+
}
|
|
8
54
|
|
|
9
55
|
/**
|
|
10
56
|
* Extracts the underlying cause from a simulation-related error.
|
|
@@ -16,10 +62,7 @@ import { isSolanaError } from './error';
|
|
|
16
62
|
*
|
|
17
63
|
* If the provided error is not a simulation-related error, it is returned unchanged.
|
|
18
64
|
*
|
|
19
|
-
*
|
|
20
|
-
* - {@link SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE}
|
|
21
|
-
* - {@link SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT}
|
|
22
|
-
* - {@link SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_RESOURCE_LIMITS}
|
|
65
|
+
* See {@link isSimulationError} for the list of error codes considered simulation errors.
|
|
23
66
|
*
|
|
24
67
|
* @param error - The error to unwrap.
|
|
25
68
|
* @return The underlying cause if the error is a simulation error, otherwise the original error.
|
|
@@ -38,12 +81,7 @@ import { isSolanaError } from './error';
|
|
|
38
81
|
* ```
|
|
39
82
|
*/
|
|
40
83
|
export function unwrapSimulationError(error: unknown): unknown {
|
|
41
|
-
|
|
42
|
-
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,
|
|
43
|
-
SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,
|
|
44
|
-
SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_RESOURCE_LIMITS,
|
|
45
|
-
];
|
|
46
|
-
if (isSolanaError(error) && !!error.cause && simulationCodes.includes(error.context.__code)) {
|
|
84
|
+
if (isSimulationError(error) && !!error.cause) {
|
|
47
85
|
return error.cause;
|
|
48
86
|
}
|
|
49
87
|
return error;
|