diff --git a/packages/snaps-sdk/src/error-wrappers.test.ts b/packages/snaps-sdk/src/error-wrappers.test.ts index 38b4dcfc5b..d45d84ea06 100644 --- a/packages/snaps-sdk/src/error-wrappers.test.ts +++ b/packages/snaps-sdk/src/error-wrappers.test.ts @@ -60,6 +60,17 @@ describe('Snap errors', () => { expect(wrapped.message).toBe('Internal JSON-RPC error.'); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new InternalError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe('Internal JSON-RPC error.'); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('InvalidInputError', () => { @@ -103,6 +114,17 @@ describe('Snap errors', () => { expect(wrapped.message).toBe('Invalid input.'); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new InvalidInputError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe('Invalid input.'); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('InvalidParamsError', () => { @@ -146,6 +168,17 @@ describe('Snap errors', () => { expect(wrapped.message).toBe('Invalid method parameter(s).'); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new InvalidParamsError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe('Invalid method parameter(s).'); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('InvalidRequestError', () => { @@ -191,6 +224,19 @@ describe('Snap errors', () => { 'The JSON sent is not a valid Request object.', ); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new InvalidRequestError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe( + 'The JSON sent is not a valid Request object.', + ); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('LimitExceededError', () => { @@ -234,6 +280,17 @@ describe('Snap errors', () => { expect(wrapped.message).toBe('Request limit exceeded.'); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new LimitExceededError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe('Request limit exceeded.'); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('MethodNotFoundError', () => { @@ -279,6 +336,19 @@ describe('Snap errors', () => { 'The method does not exist / is not available.', ); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new MethodNotFoundError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe( + 'The method does not exist / is not available.', + ); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('MethodNotSupportedError', () => { @@ -322,6 +392,17 @@ describe('Snap errors', () => { expect(wrapped.message).toBe('Method not supported.'); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new MethodNotSupportedError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe('Method not supported.'); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('ParseError', () => { @@ -367,6 +448,19 @@ describe('Snap errors', () => { 'Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.', ); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new ParseError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe( + 'Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.', + ); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('ResourceNotFoundError', () => { @@ -410,6 +504,17 @@ describe('Snap errors', () => { expect(wrapped.message).toBe('Resource not found.'); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new ResourceNotFoundError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe('Resource not found.'); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('ResourceUnavailableError', () => { @@ -453,6 +558,17 @@ describe('Snap errors', () => { expect(wrapped.message).toBe('Resource unavailable.'); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new ResourceUnavailableError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe('Resource unavailable.'); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('TransactionRejected', () => { @@ -496,6 +612,17 @@ describe('Snap errors', () => { expect(wrapped.message).toBe('Transaction rejected.'); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new TransactionRejected({ + foo: 'bar', + }); + + expect(wrapped.message).toBe('Transaction rejected.'); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('ChainDisconnectedError', () => { @@ -541,6 +668,19 @@ describe('Snap errors', () => { 'The provider is disconnected from the specified chain.', ); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new ChainDisconnectedError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe( + 'The provider is disconnected from the specified chain.', + ); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('DisconnectedError', () => { @@ -586,6 +726,19 @@ describe('Snap errors', () => { 'The provider is disconnected from all chains.', ); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new DisconnectedError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe( + 'The provider is disconnected from all chains.', + ); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('UnauthorizedError', () => { @@ -631,6 +784,19 @@ describe('Snap errors', () => { 'The requested account and/or method has not been authorized by the user.', ); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new UnauthorizedError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe( + 'The requested account and/or method has not been authorized by the user.', + ); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('UnsupportedMethodError', () => { @@ -676,6 +842,19 @@ describe('Snap errors', () => { 'The requested method is not supported by this Ethereum provider.', ); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new UnsupportedMethodError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe( + 'The requested method is not supported by this Ethereum provider.', + ); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); describe('UserRejectedRequestError', () => { @@ -719,5 +898,16 @@ describe('Snap errors', () => { expect(wrapped.message).toBe('User rejected the request.'); }); + + it('creates a SnapError without a message and with data', () => { + const wrapped = new UserRejectedRequestError({ + foo: 'bar', + }); + + expect(wrapped.message).toBe('User rejected the request.'); + expect(wrapped.data).toStrictEqual({ + foo: 'bar', + }); + }); }); }); diff --git a/packages/snaps-sdk/src/internals/error-wrappers.ts b/packages/snaps-sdk/src/internals/error-wrappers.ts index 2a35bab03a..74feebfbf2 100644 --- a/packages/snaps-sdk/src/internals/error-wrappers.ts +++ b/packages/snaps-sdk/src/internals/error-wrappers.ts @@ -18,9 +18,53 @@ export type JsonRpcErrorFunction = typeof rpcErrors.parse; */ export function createSnapError(fn: JsonRpcErrorFunction) { return class SnapJsonRpcError extends SnapError { - constructor(message?: string, data?: Record) { - const error = fn(message); + /** + * Create a new `SnapJsonRpcError` from a message. + * + * @param message - The message to create the error from. + */ + constructor(message?: string); + + /** + * Create a new `SnapJsonRpcError` from data. + * + * @param data - The data to create the error from. + */ + constructor(data?: Record); + + /** + * Create a new `SnapJsonRpcError` from a message and data. + * + * @param message - The message to create the error from. + * @param data - The data to create the error from. + */ + constructor( + message?: string | Record, + data?: Record, + ); + /** + * Create a new `SnapJsonRpcError` from a message and data. + * + * @param message - The message to create the error from. + * @param data - The data to create the error from. + */ + constructor( + message?: string | Record, + data?: Record, + ) { + if (typeof message === 'object') { + const error = fn(); + super({ + code: error.code, + message: error.message, + data: message, + }); + + return; + } + + const error = fn(message); super({ code: error.code, message: error.message,