UNPKG

@metamask/snaps-utils

Version:
189 lines 7.99 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _WrappedSnapError_error, _WrappedSnapError_message, _WrappedSnapError_stack; Object.defineProperty(exports, "__esModule", { value: true }); exports.unwrapError = exports.isWrappedSnapError = exports.isSerializedSnapError = exports.isSnapError = exports.WrappedSnapError = exports.SNAP_ERROR_WRAPPER_MESSAGE = exports.SNAP_ERROR_WRAPPER_CODE = void 0; const rpc_errors_1 = require("@metamask/rpc-errors"); const snaps_sdk_1 = require("@metamask/snaps-sdk"); const utils_1 = require("@metamask/utils"); exports.SNAP_ERROR_WRAPPER_CODE = -31001; exports.SNAP_ERROR_WRAPPER_MESSAGE = 'Wrapped Snap Error'; class WrappedSnapError extends Error { /** * Create a new `WrappedSnapError`. * * @param error - The error to create the `WrappedSnapError` from. */ constructor(error) { const message = (0, snaps_sdk_1.getErrorMessage)(error); super(message); _WrappedSnapError_error.set(this, void 0); _WrappedSnapError_message.set(this, void 0); _WrappedSnapError_stack.set(this, void 0); __classPrivateFieldSet(this, _WrappedSnapError_error, error, "f"); __classPrivateFieldSet(this, _WrappedSnapError_message, message, "f"); __classPrivateFieldSet(this, _WrappedSnapError_stack, (0, snaps_sdk_1.getErrorStack)(error), "f"); } /** * The error name. * * @returns The error name. */ get name() { return 'WrappedSnapError'; } /** * The error message. * * @returns The error message. */ get message() { return __classPrivateFieldGet(this, _WrappedSnapError_message, "f"); } /** * The error stack. * * @returns The error stack. */ get stack() { return __classPrivateFieldGet(this, _WrappedSnapError_stack, "f"); } /** * Convert the error to a JSON object. * * @returns The JSON object. */ toJSON() { const cause = isSnapError(__classPrivateFieldGet(this, _WrappedSnapError_error, "f")) ? __classPrivateFieldGet(this, _WrappedSnapError_error, "f").serialize() : (0, rpc_errors_1.serializeCause)(__classPrivateFieldGet(this, _WrappedSnapError_error, "f")); return { code: exports.SNAP_ERROR_WRAPPER_CODE, message: exports.SNAP_ERROR_WRAPPER_MESSAGE, data: { cause, }, }; } /** * Serialize the error to a JSON object. This is called by * `@metamask/rpc-errors` when serializing the error. * * @returns The JSON object. */ serialize() { return this.toJSON(); } } exports.WrappedSnapError = WrappedSnapError; _WrappedSnapError_error = new WeakMap(), _WrappedSnapError_message = new WeakMap(), _WrappedSnapError_stack = new WeakMap(); /** * Check if an object is a `SnapError`. * * @param error - The object to check. * @returns Whether the object is a `SnapError`. */ function isSnapError(error) { if ((0, utils_1.isObject)(error) && 'serialize' in error && typeof error.serialize === 'function') { const serialized = error.serialize(); return (0, utils_1.isJsonRpcError)(serialized) && isSerializedSnapError(serialized); } return false; } exports.isSnapError = isSnapError; /** * Check if a JSON-RPC error is a `SnapError`. * * @param error - The object to check. * @returns Whether the object is a `SnapError`. */ function isSerializedSnapError(error) { return error.code === snaps_sdk_1.SNAP_ERROR_CODE && error.message === snaps_sdk_1.SNAP_ERROR_MESSAGE; } exports.isSerializedSnapError = isSerializedSnapError; /** * Check if a JSON-RPC error is a `WrappedSnapError`. * * @param error - The object to check. * @returns Whether the object is a `WrappedSnapError`. */ function isWrappedSnapError(error) { return ((0, utils_1.isJsonRpcError)(error) && error.code === exports.SNAP_ERROR_WRAPPER_CODE && error.message === exports.SNAP_ERROR_WRAPPER_MESSAGE); } exports.isWrappedSnapError = isWrappedSnapError; /** * Get a JSON-RPC error with the given code, message, stack, and data. * * @param code - The error code. * @param message - The error message. * @param stack - The error stack. * @param data - Additional data for the error. * @returns The JSON-RPC error. */ function getJsonRpcError(code, message, stack, data) { const error = new rpc_errors_1.JsonRpcError(code, message, data); error.stack = stack; return error; } /** * Attempt to unwrap an unknown error to a `JsonRpcError`. This function will * try to get the error code, message, and data from the error, and return a * `JsonRpcError` with those properties. * * @param error - The error to unwrap. * @returns A tuple containing the unwrapped error and a boolean indicating * whether the error was handled. */ function unwrapError(error) { // This logic is a bit complicated, but it's necessary to handle all the // different types of errors that can be thrown by a Snap. // If the error is a wrapped Snap error, unwrap it. if (isWrappedSnapError(error)) { // The wrapped error can be a JSON-RPC error, or an unknown error. If it's // a JSON-RPC error, we can unwrap it further. if ((0, utils_1.isJsonRpcError)(error.data.cause)) { // If the JSON-RPC error is a wrapped Snap error, unwrap it further. if (isSerializedSnapError(error.data.cause)) { const { code, message, stack, data } = error.data.cause.data.cause; return [getJsonRpcError(code, message, stack, data), true]; } // Otherwise, we use the original JSON-RPC error. const { code, message, stack, data } = error.data.cause; return [getJsonRpcError(code, message, stack, data), false]; } // Otherwise, we throw an internal error with the wrapped error as the // message. return [ getJsonRpcError(rpc_errors_1.errorCodes.rpc.internal, (0, snaps_sdk_1.getErrorMessage)(error.data.cause), (0, snaps_sdk_1.getErrorStack)(error.data.cause)), false, ]; } // The error can be a non-wrapped JSON-RPC error, in which case we can just // re-throw it with the same code, message, and data. if ((0, utils_1.isJsonRpcError)(error)) { const { code, message, stack, data } = error; return [getJsonRpcError(code, message, stack, data), false]; } // If the error is not a wrapped error, we don't know how to handle it, so we // throw an internal error with the error as the message. return [ getJsonRpcError(rpc_errors_1.errorCodes.rpc.internal, (0, snaps_sdk_1.getErrorMessage)(error), (0, snaps_sdk_1.getErrorStack)(error)), false, ]; } exports.unwrapError = unwrapError; //# sourceMappingURL=errors.cjs.map