diff --git a/packages/data-fetcher/src/blockchain/retryableContract.spec.ts b/packages/data-fetcher/src/blockchain/retryableContract.spec.ts index 3d9447633..319e6d45f 100644 --- a/packages/data-fetcher/src/blockchain/retryableContract.spec.ts +++ b/packages/data-fetcher/src/blockchain/retryableContract.spec.ts @@ -98,7 +98,7 @@ describe("RetryableContract", () => { expect(result).toBe(functionResult); }); - describe("when throws a permanent call exception function error", () => { + describe("when throws a permanent execution reverted error", () => { const callExceptionError = { code: 3, shortMessage: "execution reverted...", @@ -125,6 +125,33 @@ describe("RetryableContract", () => { }); }); + describe("when throws a permanent could not decode result data error", () => { + const callExceptionError = { + code: "BAD_DATA", + shortMessage: "could not decode result data...", + }; + + beforeEach(() => { + (ethers.Contract as any as jest.Mock).mockReturnValue({ + contractFn: async () => { + throw callExceptionError; + }, + }); + + contract = new RetryableContract(tokenAddress, utils.IERC20, providerMock); + }); + + it("throws an error", async () => { + expect.assertions(1); + + try { + await contract.contractFn(); + } catch (e) { + expect(e).toBe(callExceptionError); + } + }); + }); + describe("when throws an invalid argument function error", () => { const invalidArgumentError = { code: "INVALID_ARGUMENT", diff --git a/packages/data-fetcher/src/blockchain/retryableContract.ts b/packages/data-fetcher/src/blockchain/retryableContract.ts index 1e2f23366..b27537c12 100644 --- a/packages/data-fetcher/src/blockchain/retryableContract.ts +++ b/packages/data-fetcher/src/blockchain/retryableContract.ts @@ -21,7 +21,13 @@ const PERMANENT_ERRORS: ErrorCode[] = [ const shouldRetry = (error: EthersError): boolean => { const isPermanentErrorCode = PERMANENT_ERRORS.find((errorCode) => isError(error, errorCode)); - return !isPermanentErrorCode && !(error.code === 3 && error.shortMessage?.startsWith("execution reverted")); + return ( + !isPermanentErrorCode && + // example block mainnet 47752810 + !(error.code === 3 && error.shortMessage?.startsWith("execution reverted")) && + // example block mainnet 47819836 + !(error.code === "BAD_DATA" && error.shortMessage?.startsWith("could not decode result data")) + ); }; const retryableFunctionCall = async ( diff --git a/packages/worker/src/blockchain/retryableContract.spec.ts b/packages/worker/src/blockchain/retryableContract.spec.ts index a8e78f65a..59a05d25e 100644 --- a/packages/worker/src/blockchain/retryableContract.spec.ts +++ b/packages/worker/src/blockchain/retryableContract.spec.ts @@ -90,10 +90,37 @@ describe("RetryableContract", () => { expect(result).toBe(functionResult); }); - describe("when throws a permanent call exception function error", () => { + describe("when throws a permanent execution reverted error", () => { const callExceptionError = { code: 3, - shortMessage: "execution reverted ....", + shortMessage: "execution reverted...", + }; + + beforeEach(() => { + (ethers.Contract as any as jest.Mock).mockReturnValue({ + contractFn: async () => { + throw callExceptionError; + }, + }); + + contract = new RetryableContract(tokenAddress, utils.IERC20, providerMock); + }); + + it("throws an error", async () => { + expect.assertions(1); + + try { + await contract.contractFn(); + } catch (e) { + expect(e).toBe(callExceptionError); + } + }); + }); + + describe("when throws a permanent could not decode result data error", () => { + const callExceptionError = { + code: "BAD_DATA", + shortMessage: "could not decode result data...", }; beforeEach(() => { diff --git a/packages/worker/src/blockchain/retryableContract.ts b/packages/worker/src/blockchain/retryableContract.ts index e6f398757..fcd327dfc 100644 --- a/packages/worker/src/blockchain/retryableContract.ts +++ b/packages/worker/src/blockchain/retryableContract.ts @@ -18,7 +18,13 @@ const PERMANENT_ERRORS: ErrorCode[] = [ const shouldRetry = (error: EthersError): boolean => { const isPermanentErrorCode = PERMANENT_ERRORS.find((errorCode) => isError(error, errorCode)); - return !isPermanentErrorCode && !(error.code === 3 && error.shortMessage?.startsWith("execution reverted")); + return ( + !isPermanentErrorCode && + // example block mainnet 47752810 + !(error.code === 3 && error.shortMessage?.startsWith("execution reverted")) && + // example block mainnet 47819836 + !(error.code === "BAD_DATA" && error.shortMessage?.startsWith("could not decode result data")) + ); }; const retryableFunctionCall = async (