diff --git a/packages/data-fetcher/src/blockchain/retryableContract.spec.ts b/packages/data-fetcher/src/blockchain/retryableContract.spec.ts index 248831a4e..3d9447633 100644 --- a/packages/data-fetcher/src/blockchain/retryableContract.spec.ts +++ b/packages/data-fetcher/src/blockchain/retryableContract.spec.ts @@ -100,13 +100,8 @@ describe("RetryableContract", () => { describe("when throws a permanent call exception function error", () => { const callExceptionError = { - code: "CALL_EXCEPTION", - method: "contractFn(address)", - transaction: { - data: "0x00", - to: "to", - }, - message: "call revert exception ....", + code: 3, + shortMessage: "execution reverted...", }; beforeEach(() => { @@ -209,7 +204,7 @@ describe("RetryableContract", () => { describe("when throws a few errors with no method or message before returning a result", () => { const functionResult = "functionResult"; const error = new Error(); - (error as any).code = "CALL_EXCEPTION"; + (error as any).code = 3; beforeEach(() => { let countOfFailedRequests = 0; diff --git a/packages/data-fetcher/src/blockchain/retryableContract.ts b/packages/data-fetcher/src/blockchain/retryableContract.ts index b490aeb54..1e2f23366 100644 --- a/packages/data-fetcher/src/blockchain/retryableContract.ts +++ b/packages/data-fetcher/src/blockchain/retryableContract.ts @@ -1,18 +1,13 @@ import { Logger } from "@nestjs/common"; import { setTimeout } from "timers/promises"; -import { Contract, Interface, ContractRunner, ErrorCode } from "ethers"; +import { Contract, Interface, ContractRunner, ErrorCode, isError } from "ethers"; import config from "../config"; const { blockchain } = config(); interface EthersError { - code: ErrorCode; - method: string; - transaction: { - data: string; - to: string; - }; - message: string; + code: ErrorCode | number; + shortMessage: string; } const MAX_RETRY_INTERVAL = 60000; @@ -24,16 +19,9 @@ const PERMANENT_ERRORS: ErrorCode[] = [ "NOT_IMPLEMENTED", ]; -const shouldRetry = (calledFunctionName: string, error: EthersError): boolean => { - return ( - !PERMANENT_ERRORS.includes(error.code) && - !( - error.code === "CALL_EXCEPTION" && - error.method?.startsWith(`${calledFunctionName}(`) && - !!error.transaction && - error.message?.startsWith("call revert exception") - ) - ); +const shouldRetry = (error: EthersError): boolean => { + const isPermanentErrorCode = PERMANENT_ERRORS.find((errorCode) => isError(error, errorCode)); + return !isPermanentErrorCode && !(error.code === 3 && error.shortMessage?.startsWith("execution reverted")); }; const retryableFunctionCall = async ( @@ -48,7 +36,7 @@ const retryableFunctionCall = async ( try { return await result; } catch (error) { - const isRetryable = shouldRetry(functionName, error); + const isRetryable = shouldRetry(error); if (!isRetryable) { logger.warn({ message: `Requested contract function ${functionName} failed to execute, not retryable`, diff --git a/packages/worker/src/blockchain/retryableContract.spec.ts b/packages/worker/src/blockchain/retryableContract.spec.ts index 8188112b2..a8e78f65a 100644 --- a/packages/worker/src/blockchain/retryableContract.spec.ts +++ b/packages/worker/src/blockchain/retryableContract.spec.ts @@ -92,13 +92,8 @@ describe("RetryableContract", () => { describe("when throws a permanent call exception function error", () => { const callExceptionError = { - code: "CALL_EXCEPTION", - method: "contractFn(address)", - transaction: { - data: "0x00", - to: "to", - }, - message: "call revert exception ....", + code: 3, + shortMessage: "execution reverted ....", }; beforeEach(() => { diff --git a/packages/worker/src/blockchain/retryableContract.ts b/packages/worker/src/blockchain/retryableContract.ts index 409113fe2..e6f398757 100644 --- a/packages/worker/src/blockchain/retryableContract.ts +++ b/packages/worker/src/blockchain/retryableContract.ts @@ -1,15 +1,10 @@ import { Logger } from "@nestjs/common"; import { setTimeout } from "timers/promises"; -import { Contract, Interface, ContractRunner, ErrorCode } from "ethers"; +import { Contract, Interface, ContractRunner, ErrorCode, isError } from "ethers"; interface EthersError { - code: ErrorCode; - method: string; - transaction: { - data: string; - to: string; - }; - message: string; + code: ErrorCode | number; + shortMessage: string; } const MAX_RETRY_INTERVAL = 60000; @@ -21,16 +16,9 @@ const PERMANENT_ERRORS: ErrorCode[] = [ "NOT_IMPLEMENTED", ]; -const shouldRetry = (calledFunctionName: string, error: EthersError): boolean => { - return ( - !PERMANENT_ERRORS.includes(error.code) && - !( - error.code === "CALL_EXCEPTION" && - error.method?.startsWith(`${calledFunctionName}(`) && - !!error.transaction && - error.message?.startsWith("call revert exception") - ) - ); +const shouldRetry = (error: EthersError): boolean => { + const isPermanentErrorCode = PERMANENT_ERRORS.find((errorCode) => isError(error, errorCode)); + return !isPermanentErrorCode && !(error.code === 3 && error.shortMessage?.startsWith("execution reverted")); }; const retryableFunctionCall = async ( @@ -44,7 +32,7 @@ const retryableFunctionCall = async ( try { return await result; } catch (error) { - const isRetryable = shouldRetry(functionName, error); + const isRetryable = shouldRetry(error); logger.warn({ message: `Requested contract function ${functionName} failed to execute, ${ isRetryable ? "retrying..." : "not retryable"