UNPKG

@metamask/snaps-sdk

Version:

A library containing the core functionality for building MetaMask Snaps

1 lines 9.19 kB
{"version":3,"file":"errors.mjs","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Json, JsonRpcError } from '@metamask/utils';\nimport { isJsonRpcError, isObject } from '@metamask/utils';\n\nimport {\n getErrorCause,\n getErrorCode,\n getErrorData,\n getErrorMessage,\n getErrorName,\n getErrorStack,\n SNAP_ERROR_CODE,\n SNAP_ERROR_MESSAGE,\n} from './internals';\nimport type { TrackableError } from './types';\n\n/**\n * A generic error which can be thrown by a Snap, without it causing the Snap to\n * crash.\n */\nexport class SnapError extends Error {\n readonly #code: number;\n\n readonly #message: string;\n\n readonly #data?: Record<string, Json>;\n\n readonly #stack?: string;\n\n /**\n * Create a new `SnapError`.\n *\n * @param error - The error to create the `SnapError` from. If this is a\n * `string`, it will be used as the error message. If this is an `Error`, its\n * `message` property will be used as the error message. If this is a\n * `JsonRpcError`, its `message` property will be used as the error message\n * and its `code` property will be used as the error code. Otherwise, the\n * error will be converted to a string and used as the error message.\n * @param data - Additional data to include in the error. This will be merged\n * with the error data, if any.\n */\n constructor(\n error: string | Error | JsonRpcError,\n data: Record<string, Json> = {},\n ) {\n const message = getErrorMessage(error);\n super(message);\n\n this.#message = message;\n this.#code = getErrorCode(error);\n\n const mergedData = { ...getErrorData(error), ...data };\n if (Object.keys(mergedData).length > 0) {\n this.#data = mergedData;\n }\n\n this.#stack = super.stack;\n }\n\n /**\n * The error name.\n *\n * @returns The error name.\n */\n get name() {\n return 'SnapError';\n }\n\n /**\n * The error code.\n *\n * @returns The error code.\n */\n get code() {\n return this.#code;\n }\n\n /**\n * The error message.\n *\n * @returns The error message.\n */\n // This line is covered, but Jest doesn't pick it up for some reason.\n /* istanbul ignore next */\n get message() {\n return this.#message;\n }\n\n /**\n * Additional data for the error.\n *\n * @returns Additional data for the error.\n */\n get data() {\n return this.#data;\n }\n\n /**\n * The error stack.\n *\n * @returns The error stack.\n */\n // This line is covered, but Jest doesn't pick it up for some reason.\n /* istanbul ignore next */\n get stack() {\n return this.#stack;\n }\n\n /**\n * Convert the error to a JSON object.\n *\n * @returns The JSON object.\n */\n toJSON(): SerializedSnapError {\n return {\n code: SNAP_ERROR_CODE,\n message: SNAP_ERROR_MESSAGE,\n data: {\n cause: {\n code: this.code,\n message: this.message,\n stack: this.stack,\n ...(this.data ? { data: this.data } : {}),\n },\n },\n };\n }\n\n /**\n * Serialize the error to a JSON object. This is called by\n * `@metamask/rpc-errors` when serializing the error.\n *\n * @returns The JSON object.\n */\n serialize() {\n return this.toJSON();\n }\n}\n\n/**\n * A serialized {@link SnapError}. It's JSON-serializable, so it can be sent\n * over the RPC. The original error is wrapped in the `cause` property.\n *\n * @property code - The error code. This is always `-31002`.\n * @property message - The error message. This is always `'Snap Error'`.\n * @property data - The error data.\n * @property data.cause - The cause of the error.\n * @property data.cause.code - The error code.\n * @property data.cause.message - The error message.\n * @property data.cause.stack - The error stack.\n * @property data.cause.data - Additional data for the error.\n * @see SnapError\n */\nexport type SerializedSnapError = {\n code: typeof SNAP_ERROR_CODE;\n message: typeof SNAP_ERROR_MESSAGE;\n data: {\n cause: JsonRpcError;\n };\n};\n\n/**\n * Get a serialised JSON error from a given error. This is intended to be used\n * with `snap_trackError` to convert an error to a JSON object that can be\n * tracked by the Sentry instance in the client.\n *\n * @param error - The error to convert to a JSON error. This can be a string, an\n * `Error`, a `JsonRpcError`, or any other type. If it is not a string or an\n * `Error`, it will be converted to a string using its `toString()` method.\n * @returns A JSON object containing the error message and stack trace, if\n * available.\n * @example\n * try {\n * // Some code that may throw an error\n * } catch (error) {\n * await snap.request({\n * method: 'snap_trackError',\n * params: {\n * error: getJsonError(error),\n * },\n * });\n * }\n */\nexport function getJsonError(\n // TypeScript will narrow this to `unknown`, but we specify all the types for\n // clarity.\n error: string | Error | JsonRpcError | unknown,\n): TrackableError {\n if (typeof error === 'string') {\n return {\n name: 'Error',\n message: error,\n stack: null,\n cause: null,\n };\n }\n\n if (isJsonRpcError(error)) {\n return {\n name: 'JsonRpcError',\n message: getErrorMessage(error),\n stack: getErrorStack(error) ?? getErrorStack(error.data) ?? null,\n cause: null,\n };\n }\n\n const cause = getErrorCause(error);\n\n return {\n name: getErrorName(error),\n message: getErrorMessage(error),\n stack: getErrorStack(error) ?? null,\n cause: cause === null ? null : getJsonError(cause),\n };\n}\n\n/**\n * Check if a JSON-RPC error is a `SnapError`.\n *\n * @param error - The object to check.\n * @returns Whether the object is a `SnapError`.\n */\nexport function isSerializedSnapError(\n error: JsonRpcError,\n): error is SerializedSnapError {\n return error.code === SNAP_ERROR_CODE && error.message === SNAP_ERROR_MESSAGE;\n}\n\n/**\n * Check if an object is a `SnapError`.\n *\n * @param error - The object to check.\n * @returns Whether the object is a `SnapError`.\n */\nexport function isSnapError(error: unknown): error is SnapError {\n if (\n isObject(error) &&\n 'serialize' in error &&\n typeof error.serialize === 'function'\n ) {\n const serialized = error.serialize();\n return isJsonRpcError(serialized) && isSerializedSnapError(serialized);\n }\n\n return false;\n}\n"]}