import { SolanaErrorCode } from './codes'; import { SolanaErrorContext } from './context'; import { SolanaError } from './error'; import { safeCaptureStackTrace } from './stack-trace'; type Config = Readonly<{ /** * Oh, hello. You might wonder what in tarnation is going on here. Allow us to explain. * * One of the goals of `@solana/errors` is to allow errors that are not interesting to your * application to shake out of your app bundle in production. This means that we must never * export large hardcoded maps of error codes/messages. * * Unfortunately, where instruction and transaction errors from the RPC are concerned, we have * no choice but to keep a map between the RPC `rpcEnumError` enum name and its corresponding * `SolanaError` code. In the interest of implementing that map in as few bytes of source code * as possible, we do the following: * * 1. Reserve a block of sequential error codes for the enum in question * 2. Hardcode the list of enum names in that same order * 3. Match the enum error name from the RPC with its index in that list, and reconstruct the * `SolanaError` code by adding the `errorCodeBaseOffset` to that index */ errorCodeBaseOffset: number; getErrorContext: ( errorCode: SolanaErrorCode, rpcErrorName: string, rpcErrorContext?: unknown, ) => SolanaErrorContext[SolanaErrorCode]; orderedErrorNames: string[]; rpcEnumError: string | { [key: string]: unknown }; }>; export function getSolanaErrorFromRpcError( { errorCodeBaseOffset, getErrorContext, orderedErrorNames, rpcEnumError }: Config, // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type constructorOpt: Function, ): SolanaError { let rpcErrorName; let rpcErrorContext; if (typeof rpcEnumError === 'string') { rpcErrorName = rpcEnumError; } else { rpcErrorName = Object.keys(rpcEnumError)[0]; rpcErrorContext = rpcEnumError[rpcErrorName]; } const codeOffset = orderedErrorNames.indexOf(rpcErrorName); const errorCode = (errorCodeBaseOffset + codeOffset) as SolanaErrorCode; const errorContext = getErrorContext(errorCode, rpcErrorName, rpcErrorContext); const err = new SolanaError(errorCode, errorContext); safeCaptureStackTrace(err, constructorOpt); return err; }