Skip to content

Commit 4b2618a

Browse files
committed
🐛 common: handle viem reverts
1 parent 757bb3d commit 4b2618a

2 files changed

Lines changed: 32 additions & 20 deletions

File tree

common/revertReason.ts

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,38 @@
1-
import { BaseError, ContractFunctionRevertedError } from "viem";
1+
type ContractFunctionReverted = {
2+
data?: { args?: readonly unknown[]; errorName?: string };
3+
name: "ContractFunctionRevertedError";
4+
reason?: string;
5+
signature?: string;
6+
};
27

38
type Fallback = "message" | "name" | "string" | "unknown";
49

510
export default function revertReason(
611
error?: unknown,
712
{ fallback = "name", withArguments = false }: { fallback?: Fallback; withArguments?: boolean } = {},
813
): string {
9-
const cause = error instanceof BaseError ? error.walk((r) => r instanceof ContractFunctionRevertedError) : undefined;
10-
return cause instanceof ContractFunctionRevertedError
11-
? withArguments && cause.data?.errorName
12-
? `${cause.data.errorName}(${cause.data.args?.map(String).join(",") ?? ""})`
13-
: (cause.data?.errorName ?? cause.reason ?? cause.signature ?? "unknown")
14-
: fallback === "message"
15-
? error instanceof Error
16-
? error.message
17-
: String(error)
18-
: fallback === "string"
19-
? String(error)
20-
: fallback === "unknown"
21-
? "unknown"
22-
: error instanceof Error
23-
? error.name
24-
: "unknown";
14+
const cause = findRevertedCause(error);
15+
if (cause) {
16+
if (withArguments && cause.data?.errorName) {
17+
return `${cause.data.errorName}(${cause.data.args?.map(String).join(",") ?? ""})`;
18+
}
19+
return cause.data?.errorName ?? cause.reason ?? cause.signature ?? "unknown";
20+
}
21+
if (fallback === "message") return error instanceof Error ? error.message : String(error);
22+
if (fallback === "string") return String(error);
23+
if (fallback === "unknown") return "unknown";
24+
return error instanceof Error ? error.name : "unknown";
25+
}
26+
27+
export function findRevertedCause(error: unknown): ContractFunctionReverted | undefined {
28+
for (
29+
let cause: unknown = error;
30+
cause != null && typeof cause === "object";
31+
cause = (cause as { cause?: unknown }).cause
32+
) {
33+
if ("name" in cause && (cause as { name?: unknown }).name === "ContractFunctionRevertedError") {
34+
return cause as ContractFunctionReverted;
35+
}
36+
}
37+
return undefined;
2538
}

src/utils/reportError.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { captureException, withScope } from "@sentry/react-native";
2-
import { BaseError, ContractFunctionRevertedError } from "viem";
32

4-
import revertReason from "@exactly/common/revertReason";
3+
import revertReason, { findRevertedCause } from "@exactly/common/revertReason";
54

65
export default function reportError(error: unknown, hint?: Parameters<typeof captureException>[1]) {
76
const parsed = parseError(error);
@@ -104,7 +103,7 @@ function parseError(error: unknown) {
104103
root.message.length > 0
105104
? normalizeMessage(root.message)
106105
: undefined;
107-
const revert = error instanceof BaseError && error.walk((r) => r instanceof ContractFunctionRevertedError) !== null;
106+
const revert = findRevertedCause(error) !== undefined;
108107
const reason = revertReason(error, { fallback: "unknown" });
109108
return { code, message, name, reason, revert, status };
110109
}

0 commit comments

Comments
 (0)