Skip to content

Commit 4041bed

Browse files
committed
add pretty error message back
1 parent d0b372e commit 4041bed

File tree

8 files changed

+66
-18
lines changed

8 files changed

+66
-18
lines changed

src/server/routes/contract/extensions/erc721/write/lazyMint.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const requestBodySchema = Type.Object({
2323

2424
requestBodySchema.examples = [
2525
{
26-
metadata: [
26+
metadatas: [
2727
{
2828
name: "My NFT #1",
2929
description: "My NFT #1 description",

src/server/schemas/wallet/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const walletHeaderSchema = Type.Object({
88
}),
99
"x-idempotency-key": Type.Optional(
1010
Type.String({
11-
description: `A string that uniquely identifies this transaction. Submitting the same idempotency key will not enqueue a new transaction for ${env.PRUNE_TRANSACTIONS} day(s).`,
11+
description: `Multiple transactions submitted with the same idempotency key will not send a new transaction for ${env.PRUNE_TRANSACTIONS} day(s).`,
1212
}),
1313
),
1414
});

src/utils/env.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ export const env = createEnv({
7979
.nonnegative()
8080
.default(0),
8181
REDIS_URL: z.string(),
82-
SEND_TRANSACTION_QUEUE_CONCURRENCY: z.coerce.number().default(100),
83-
CONFIRM_TRANSACTION_QUEUE_CONCURRENCY: z.coerce.number().default(100),
84-
CANCEL_TRANSACTION_QUEUE_CONCURRENCY: z.coerce.number().default(100),
82+
SEND_TRANSACTION_QUEUE_CONCURRENCY: z.coerce.number().default(1000),
83+
CONFIRM_TRANSACTION_QUEUE_CONCURRENCY: z.coerce.number().default(1000),
84+
CANCEL_TRANSACTION_QUEUE_CONCURRENCY: z.coerce.number().default(1000),
8585
ENGINE_MODE: z.enum(["sandbox", "unrestricted"]).default("unrestricted"),
8686
},
8787
clientPrefix: "NEVER_USED",

src/utils/error.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { ethers } from "ethers";
2+
import { getChainMetadata } from "thirdweb/chains";
3+
import { getChain } from "./chain";
4+
import { EthersError } from "./ethers";
5+
import { simulateQueuedTransaction } from "./transaction/simulateQueuedTransaction";
6+
import { AnyTransaction } from "./transaction/types";
7+
8+
export const prettifyError = async (
9+
transaction: AnyTransaction,
10+
error: Error,
11+
): Promise<string> => {
12+
if (!transaction.isUserOp) {
13+
if (
14+
(error as unknown as EthersError)?.code ===
15+
ethers.errors.INSUFFICIENT_FUNDS
16+
) {
17+
const chain = await getChain(transaction.chainId);
18+
const metadata = await getChainMetadata(chain);
19+
return `Insufficient ${metadata.nativeCurrency?.symbol} on ${metadata.name} in ${transaction.from}.`;
20+
}
21+
22+
if (
23+
(error as unknown as EthersError)?.code ===
24+
ethers.errors.UNPREDICTABLE_GAS_LIMIT
25+
) {
26+
const simulateError = await simulateQueuedTransaction(transaction);
27+
if (simulateError) {
28+
return simulateError;
29+
}
30+
}
31+
}
32+
33+
return error.message;
34+
};

src/utils/ethers.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface EthersError {
2+
reason: string;
3+
code: string;
4+
error: any;
5+
method: string;
6+
transaction: any;
7+
}

src/utils/transaction/insertTransaction.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { randomUUID } from "crypto";
2+
import { Address } from "thirdweb";
23
import { TransactionDB } from "../../db/transactions/db";
34
import { createCustomError } from "../../server/middleware/error";
45
import { SendTransactionQueue } from "../../worker/queues/sendTransactionQueue";
@@ -16,7 +17,6 @@ export const insertTransaction = async (
1617
args: InsertTransactionData,
1718
): Promise<string> => {
1819
const { insertedTransaction, idempotencyKey, shouldSimulate = false } = args;
19-
const { value, extension } = insertedTransaction;
2020

2121
// The queueId is the idempotency key. Default to a random UUID (no idempotency).
2222
const queueId = idempotencyKey ?? randomUUID();
@@ -30,8 +30,11 @@ export const insertTransaction = async (
3030
status: "queued",
3131
queueId,
3232
queuedAt: new Date(),
33-
value: value ?? 0n,
3433
retryCount: 0,
34+
35+
from: insertedTransaction.from.toLowerCase() as Address,
36+
to: insertedTransaction.to?.toLowerCase() as Address | undefined,
37+
value: insertedTransaction.value ?? 0n,
3538
};
3639

3740
// Simulate the transaction.

src/utils/transaction/simulateQueuedTransaction.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ import { getAccount } from "../account";
1313
import { getSmartWalletV5 } from "../cache/getSmartWalletV5";
1414
import { getChain } from "../chain";
1515
import { thirdwebClient } from "../sdk";
16-
import { QueuedTransaction } from "./types";
16+
import { AnyTransaction } from "./types";
1717

1818
/**
1919
* Simulate the queued transaction.
20-
* @param queuedTransaction
20+
* @param transaction
2121
* @throws if there is a simulation error
2222
*/
2323
export const simulateQueuedTransaction = async (
24-
queuedTransaction: QueuedTransaction,
24+
transaction: AnyTransaction,
2525
): Promise<string | null> => {
2626
const {
2727
chainId,
@@ -38,11 +38,11 @@ export const simulateQueuedTransaction = async (
3838
accountAddress,
3939
target,
4040
from,
41-
} = queuedTransaction;
41+
} = transaction;
4242

4343
const chain = await getChain(chainId);
4444

45-
let transaction: PreparedTransaction;
45+
let preparedTransaction: PreparedTransaction;
4646
if (from && accountAddress && signerAddress && target && functionName) {
4747
try {
4848
// Resolve Target Contract
@@ -53,7 +53,7 @@ export const simulateQueuedTransaction = async (
5353
});
5454

5555
// Prepare UserOperation Transaction
56-
transaction = prepareContractCall({
56+
preparedTransaction = prepareContractCall({
5757
contract: targetContract,
5858
method: await resolveMethod(functionName),
5959
params: functionArgs ?? [],
@@ -65,7 +65,7 @@ export const simulateQueuedTransaction = async (
6565
}
6666
} else if (data) {
6767
// Resolve data.
68-
transaction = prepareTransaction({
68+
preparedTransaction = prepareTransaction({
6969
client: thirdwebClient,
7070
chain,
7171
to,
@@ -82,7 +82,7 @@ export const simulateQueuedTransaction = async (
8282
chain,
8383
address: to,
8484
});
85-
transaction = await prepareContractCall({
85+
preparedTransaction = await prepareContractCall({
8686
contract,
8787
method: resolveMethod(functionName),
8888
params: functionArgs,
@@ -94,7 +94,7 @@ export const simulateQueuedTransaction = async (
9494
});
9595
} else {
9696
throw new Error(
97-
`Transaction cannot be simulated: ${stringify(queuedTransaction)}`,
97+
`Transaction cannot be simulated: ${stringify(transaction)}`,
9898
);
9999
}
100100

@@ -114,7 +114,10 @@ export const simulateQueuedTransaction = async (
114114

115115
try {
116116
// Use an account to simulate the transaction to catch fund errors.
117-
await simulateTransaction({ transaction, account });
117+
await simulateTransaction({
118+
transaction: preparedTransaction,
119+
account,
120+
});
118121
return null;
119122
} catch (e: any) {
120123
// Error should be of type TransactionError in the thirdweb SDK.

src/worker/tasks/sendTransactionWorker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { getBlockNumberish } from "../../utils/block";
1111
import { getChain } from "../../utils/chain";
1212
import { msSince } from "../../utils/date";
1313
import { env } from "../../utils/env";
14+
import { prettifyError } from "../../utils/error";
1415
import { redis } from "../../utils/redis/redis";
1516
import { thirdwebClient } from "../../utils/sdk";
1617
import { simulateQueuedTransaction } from "../../utils/transaction/simulateQueuedTransaction";
@@ -276,7 +277,7 @@ _worker.on("failed", async (job: Job<string> | undefined, error: Error) => {
276277
const erroredTransaction: ErroredTransaction = {
277278
...transaction,
278279
status: "errored",
279-
errorMessage: error.message,
280+
errorMessage: await prettifyError(transaction, error),
280281
};
281282
await TransactionDB.set(erroredTransaction);
282283
await enqueueTransactionWebhook(erroredTransaction);

0 commit comments

Comments
 (0)