Skip to content

Commit

Permalink
Improve support for Snap errors without a message (#2176)
Browse files Browse the repository at this point in the history
Previously you would have to do something like `new
InternalError(undefined, { data: 'here' })`. Now you can omit the
`undefined` parameter, and simply use `new InternalError({ data: 'here'
})`.
  • Loading branch information
Mrtenz authored Feb 9, 2024
1 parent d844be7 commit 1ada339
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 2 deletions.
190 changes: 190 additions & 0 deletions packages/snaps-sdk/src/error-wrappers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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',
});
});
});
});
48 changes: 46 additions & 2 deletions packages/snaps-sdk/src/internals/error-wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, Json>) {
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<string, Json>);

/**
* 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<string, Json>,
data?: Record<string, Json>,
);

/**
* 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<string, Json>,
data?: Record<string, Json>,
) {
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,
Expand Down

0 comments on commit 1ada339

Please sign in to comment.