Skip to content

Commit

Permalink
fix: retry-failed creates undefined nonce value (#766)
Browse files Browse the repository at this point in the history
* fix: retry-failed creates undefined nonce value

* type import
  • Loading branch information
arcoraven authored Nov 8, 2024
1 parent 32961ab commit a121730
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 30 deletions.
33 changes: 21 additions & 12 deletions src/server/middleware/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,17 @@ const isZodError = (err: unknown): boolean => {

export const withErrorHandler = async (server: FastifyInstance) => {
server.setErrorHandler(
(error: Error | CustomError | ZodError, request, reply) => {
(error: string | Error | CustomError | ZodError, request, reply) => {
if (typeof error === "string") {
return reply.status(StatusCodes.INTERNAL_SERVER_ERROR).send({
error: {
statusCode: 500,
code: "INTERNAL_SERVER_ERROR",
message: error || ReasonPhrases.INTERNAL_SERVER_ERROR,
},
});
}

// Ethers Error Codes
if (parseEthersError(error)) {
return reply.status(StatusCodes.BAD_REQUEST).send({
Expand Down Expand Up @@ -103,25 +113,24 @@ export const withErrorHandler = async (server: FastifyInstance) => {
StatusCodes.INTERNAL_SERVER_ERROR;

const message = error.message ?? ReasonPhrases.INTERNAL_SERVER_ERROR;
reply.status(statusCode).send({
return reply.status(statusCode).send({
error: {
code,
message,
statusCode,
stack: env.NODE_ENV !== "production" ? error.stack : undefined,
},
});
} else {
// Handle non-custom errors
reply.status(StatusCodes.INTERNAL_SERVER_ERROR).send({
error: {
statusCode: 500,
code: "INTERNAL_SERVER_ERROR",
message: error.message || ReasonPhrases.INTERNAL_SERVER_ERROR,
stack: env.NODE_ENV !== "production" ? error.stack : undefined,
},
});
}

reply.status(StatusCodes.INTERNAL_SERVER_ERROR).send({
error: {
statusCode: 500,
code: "INTERNAL_SERVER_ERROR",
message: error.message || ReasonPhrases.INTERNAL_SERVER_ERROR,
stack: env.NODE_ENV !== "production" ? error.stack : undefined,
},
});
},
);
};
3 changes: 1 addition & 2 deletions src/server/routes/transaction/retry-failed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,9 @@ export async function retryFailedTransaction(fastify: FastifyInstance) {
);
}

// temp do not handle userop
if (transaction.isUserOp) {
throw createCustomError(
`Transaction cannot be retried because it is a userop`,
"Transaction cannot be retried because it is a userop",
StatusCodes.BAD_REQUEST,
"TRANSACTION_CANNOT_BE_RETRIED",
);
Expand Down
36 changes: 20 additions & 16 deletions src/worker/tasks/sendTransactionWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,15 @@ const handler: Processor<string, void, string> = async (job: Job<string>) => {
// For example, the developer retried all failed transactions during an RPC outage.
// An errored queued transaction (resendCount = 0) is safe to retry: the transaction wasn't sent to RPC.
if (transaction.status === "errored" && resendCount === 0) {
const { errorMessage, ...omitted } = transaction;
transaction = {
...{
...transaction,
nonce: undefined,
errorMessage: undefined,
gas: undefined,
gasPrice: undefined,
maxFeePerGas: undefined,
maxPriorityFeePerGas: undefined,
},
...omitted,
status: "queued",
resendCount: 0,
queueId: transaction.queueId,
queuedAt: transaction.queuedAt,
value: transaction.value,
data: transaction.data,
manuallyResentAt: new Date(),
} satisfies QueuedTransaction;
}
Expand Down Expand Up @@ -246,11 +244,14 @@ const _sendUserOp = async (
waitForDeployment: false,
})) as UserOperation; // TODO support entrypoint v0.7 accounts
} catch (error) {
return {
const errorMessage = wrapError(error, "Bundler").message;
const erroredTransaction: ErroredTransaction = {
...queuedTransaction,
status: "errored",
errorMessage: wrapError(error, "Bundler").message,
} satisfies ErroredTransaction;
errorMessage,
};
job.log(`Failed to populate transaction: ${errorMessage}`);
return erroredTransaction;
}

job.log(`Populated userOp: ${stringify(signedUserOp)}`);
Expand Down Expand Up @@ -322,12 +323,15 @@ const _sendTransaction = async (
maxPriorityFeePerGas: overrides?.maxPriorityFeePerGas,
},
});
} catch (e: unknown) {
return {
} catch (error: unknown) {
const errorMessage = wrapError(error, "RPC").message;
const erroredTransaction: ErroredTransaction = {
...queuedTransaction,
status: "errored",
errorMessage: wrapError(e, "RPC").message,
} satisfies ErroredTransaction;
errorMessage,
};
job.log(`Failed to populate transaction: ${errorMessage}`);
return erroredTransaction;
}

// Handle if `maxFeePerGas` is overridden.
Expand Down

0 comments on commit a121730

Please sign in to comment.