diff --git a/src/shared/utils/env.ts b/src/shared/utils/env.ts index 3db48dcb..85aaf3b9 100644 --- a/src/shared/utils/env.ts +++ b/src/shared/utils/env.ts @@ -115,6 +115,8 @@ export const env = createEnv({ .number() .gt(0.0, "scaling factor must be greater than 0") .default(1.0), + // Retry prepareUserOp errors instead of immediately failing the transaction + EXPERIMENTAL__RETRY_PREPARE_USEROP_ERRORS: boolEnvSchema(false), }, clientPrefix: "NEVER_USED", client: {}, @@ -169,6 +171,8 @@ export const env = createEnv({ process.env.EXPERIMENTAL__MINE_WORKER_MAX_POLL_INTERVAL_SECONDS, EXPERIMENTAL__MINE_WORKER_POLL_INTERVAL_SCALING_FACTOR: process.env.EXPERIMENTAL__MINE_WORKER_POLL_INTERVAL_SCALING_FACTOR, + EXPERIMENTAL__RETRY_PREPARE_USEROP_ERRORS: + process.env.EXPERIMENTAL__RETRY_PREPARE_USEROP_ERRORS, SEND_WEBHOOK_QUEUE_CONCURRENCY: process.env.SEND_WEBHOOK_QUEUE_CONCURRENCY, }, onValidationError: (error: ZodError) => { diff --git a/src/worker/tasks/send-transaction-worker.ts b/src/worker/tasks/send-transaction-worker.ts index 21615b5a..2530eea4 100644 --- a/src/worker/tasks/send-transaction-worker.ts +++ b/src/worker/tasks/send-transaction-worker.ts @@ -295,12 +295,19 @@ const _sendUserOp = async ( }); } catch (error) { const errorMessage = wrapError(error, "Bundler").message; + job.log(`Failed to populate transaction: ${errorMessage}`); + + // If retry is enabled for prepareUserOp errors, throw to trigger job retry + if (env.EXPERIMENTAL__RETRY_PREPARE_USEROP_ERRORS) { + throw error; + } + + // Otherwise, return errored transaction as before const erroredTransaction: ErroredTransaction = { ...queuedTransaction, status: "errored", errorMessage, }; - job.log(`Failed to populate transaction: ${errorMessage}`); return erroredTransaction; } @@ -356,12 +363,19 @@ const _sendUserOp = async ( const errorMessage = `${ wrapError(error, "Bundler").message } Failed to sign prepared userop`; + job.log(`Failed to sign userop: ${errorMessage}`); + + // If retry is enabled for prepareUserOp errors, throw to trigger job retry + if (env.EXPERIMENTAL__RETRY_PREPARE_USEROP_ERRORS) { + throw error; + } + + // Otherwise, return errored transaction as before const erroredTransaction: ErroredTransaction = { ...queuedTransaction, status: "errored", errorMessage, }; - job.log(`Failed to sign userop: ${errorMessage}`); return erroredTransaction; } @@ -383,12 +397,19 @@ const _sendUserOp = async ( const errorMessage = `${ wrapError(error, "Bundler").message } Failed to bundle userop`; + job.log(`Failed to bundle userop: ${errorMessage}`); + + // If retry is enabled for prepareUserOp errors, throw to trigger job retry + if (env.EXPERIMENTAL__RETRY_PREPARE_USEROP_ERRORS) { + throw error; + } + + // Otherwise, return errored transaction as before const erroredTransaction: ErroredTransaction = { ...queuedTransaction, status: "errored", errorMessage, }; - job.log(`Failed to bundle userop: ${errorMessage}`); return erroredTransaction; }