Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PRO-2171-Bundler Error Handling #104

Merged
merged 4 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# Changelog
## [1.5.3] - 2024-02-28
### Bug Fix
- Added Error Handling on bundler side
### Breaking Changes
- Removed `possibleSolution` parameter from error handling and passed that value into `message` itself and added a new parameter called `rawError` to report what the exact error is

## [1.5.2] - 2024-02-12
### New
- Added `GenericBundler` and `EtherspotBundler` as bundlerProviders and removed bundlerUrl params from SdkOptions
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@etherspot/prime-sdk",
"version": "1.5.2",
"version": "1.5.3",
"description": "Etherspot Prime (Account Abstraction) SDK",
"keywords": [
"ether",
Expand Down
42 changes: 30 additions & 12 deletions src/sdk/base/HttpRpcClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,39 @@ export class HttpRpcClient {
initializing: Promise<void>;

constructor(readonly bundlerUrl: string, readonly entryPointAddress: string, readonly chainId: number) {
this.userOpJsonRpcProvider = new ethers.providers.JsonRpcProvider(this.bundlerUrl, {
name: 'Connected bundler network',
chainId,
});
this.initializing = this.validateChainId();
try {
this.userOpJsonRpcProvider = new ethers.providers.JsonRpcProvider({
url: this.bundlerUrl
}, {
name: 'Connected bundler network',
chainId,
});
this.initializing = this.validateChainId();
} catch (err) {
if (err.message.includes('failed response'))
throw new ErrorHandler(err.message, 2);
if (err.message.includes('timeout'))
throw new ErrorHandler(err.message, 3);
throw new Error(err.message);
}
}

async validateChainId(): Promise<void> {
// validate chainId is in sync with expected chainid
const chain = await this.userOpJsonRpcProvider.send('eth_chainId', []);
const bundlerChain = parseInt(chain);
if (bundlerChain !== this.chainId) {
throw new Error(
`bundler ${this.bundlerUrl} is on chainId ${bundlerChain}, but provider is on chainId ${this.chainId}`,
);
try {
// validate chainId is in sync with expected chainid
const chain = await this.userOpJsonRpcProvider.send('eth_chainId', []);
const bundlerChain = parseInt(chain);
if (bundlerChain !== this.chainId) {
throw new Error(
`bundler ${this.bundlerUrl} is on chainId ${bundlerChain}, but provider is on chainId ${this.chainId}`,
);
}
} catch (err) {
if (err.message.includes('failed response'))
throw new ErrorHandler(err.message, 400);
if (err.message.includes('timeout'))
throw new ErrorHandler(err.message, 404);
throw new Error(err.message);
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/sdk/errorHandler/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const errorMsg = {
'429': 'Rate limit exceeded for the given bundler api key. Please contact bundler team for increasing bandwidth.', // Rate limit quota execeeded
'-32521': 'Check for balance in your Smart wallet', // execution reverted
'-32500': `Please make sure you have enough funds for wallet creation.`, // transaction rejected by entryPoint's simulateValidation, during wallet creation or validation
'-32501': `Check paymaster data`, // transaction rejected by paymaster's validatePaymasterUserOp
Expand All @@ -8,7 +9,10 @@ export const errorMsg = {
'-32505': 'Factory or Wallet or Paymaster not staked or unstake-delay is too low. Try with another entity', // transaction rejected because some entity (or signature aggregator) stake or unstake-delay is too low
'-32506': 'Please create an issue https://github.com/etherspot/etherspot-prime-sdk/issues or ticket on https://discord.etherspot.io', // transaction rejected because wallet specified unsupported signature aggregator
'-32507': 'Please create an issue https://github.com/etherspot/etherspot-prime-sdk/issues or ticket on https://discord.etherspot.io', // transaction rejected because of wallet signature check failed (or paymaster signature, if the paymaster uses its data as signature)
'1': 'Make sure the sdk fn called has valid parameters', // sdk Validation errors
'1': 'Make sure the sdk fn called has valid parameters', // sdk Validation errors,
'400': 'Either the bundler url is unreachable or the api key rate limit has reached. Please contact support for more info', // Bundler using ethers package returning SERVER_ERROR
'404': 'The request sent has reached timeout. Check your internet access or the bundler url if using etherspot bundler, the rate limit might be reached Please contact support for more info', // ethers package
'-429': 'Rate limit exceeded for the given bundler api key. Please contact bundler team for increasing bandwidth.', // Rate limit quota execeeded
}

export const entryPointErrorMsg = {
Expand Down
12 changes: 5 additions & 7 deletions src/sdk/errorHandler/errorHandler.service.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { entryPointErrorMsg, errorMsg } from "./constants";

export class ErrorHandler extends Error {
public possibleSolution: string = null;
public rawError: string = null;
constructor(public error: string, public code?: number) {
super(error);
this.error = error;
this.rawError = error;
this.code = code;
if (code) {
this.possibleSolution = errorMsg[code.toString()];
// if (error.includes('AA33 reverted')) {
// this.possibleSolution += ' If using a token, make sure that approval transaction is done for the requested operation and have enough tokens to spend for this transaction.'
// }
this.message = errorMsg[code.toString()];
if (entryPointErrorMsg[error]) {
this.possibleSolution = entryPointErrorMsg[error];
this.message = entryPointErrorMsg[error];
}

}
}
}
1 change: 0 additions & 1 deletion src/sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { DataUtils } from './dataUtils';
import { PrimeSdk } from './sdk';

export * from './api';
export * from './data';
export * from './dto';
export * from './interfaces';
export * from './network';
Expand Down
Loading