Skip to content

Commit 6c38672

Browse files
[Bridge] Improve error handling in PayEmbed
1 parent 88533d9 commit 6c38672

File tree

12 files changed

+120
-27
lines changed

12 files changed

+120
-27
lines changed

.changeset/blue-comics-doubt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Better error messages in PayEmbed

packages/thirdweb/src/bridge/Buy.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ThirdwebClient } from "../client/client.js";
44
import { getThirdwebBaseUrl } from "../utils/domains.js";
55
import { getClientFetch } from "../utils/fetch.js";
66
import { stringify } from "../utils/json.js";
7+
import { BridgeApiError } from "./types/Errors.js";
78
import type { PreparedQuote, Quote } from "./types/Quote.js";
89

910
/**
@@ -127,9 +128,12 @@ export async function quote(options: quote.Options): Promise<quote.Result> {
127128
const response = await clientFetch(url.toString());
128129
if (!response.ok) {
129130
const errorJson = await response.json();
130-
throw new Error(
131-
`${errorJson.code} | ${errorJson.message} - ${errorJson.correlationId}`,
132-
);
131+
throw new BridgeApiError({
132+
code: errorJson.code || "UNKNOWN_ERROR",
133+
message: errorJson.message || response.statusText,
134+
correlationId: errorJson.correlationId || undefined,
135+
statusCode: response.status,
136+
});
133137
}
134138

135139
const { data }: { data: Quote } = await response.json();
@@ -357,9 +361,12 @@ export async function prepare(
357361
});
358362
if (!response.ok) {
359363
const errorJson = await response.json();
360-
throw new Error(
361-
`${errorJson.code} | ${errorJson.message} - ${errorJson.correlationId}`,
362-
);
364+
throw new BridgeApiError({
365+
code: errorJson.code || "UNKNOWN_ERROR",
366+
message: errorJson.message || response.statusText,
367+
correlationId: errorJson.correlationId || undefined,
368+
statusCode: response.status,
369+
});
363370
}
364371

365372
const { data }: { data: PreparedQuote } = await response.json();

packages/thirdweb/src/bridge/Chains.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { ThirdwebClient } from "../client/client.js";
22
import { getThirdwebBaseUrl } from "../utils/domains.js";
33
import { getClientFetch } from "../utils/fetch.js";
44
import type { Chain } from "./types/Chain.js";
5+
import { BridgeApiError } from "./types/Errors.js";
56

67
/**
78
* Retrieves supported Universal Bridge chains.
@@ -59,7 +60,12 @@ export async function chains(options: chains.Options): Promise<chains.Result> {
5960
const response = await clientFetch(url.toString());
6061
if (!response.ok) {
6162
const errorJson = await response.json();
62-
throw new Error(`${errorJson.code} | ${errorJson.message}`);
63+
throw new BridgeApiError({
64+
code: errorJson.code || "UNKNOWN_ERROR",
65+
message: errorJson.message || response.statusText,
66+
correlationId: errorJson.correlationId || undefined,
67+
statusCode: response.status,
68+
});
6369
}
6470

6571
const { data }: { data: Chain[] } = await response.json();

packages/thirdweb/src/bridge/Onramp.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { ThirdwebClient } from "../client/client.js";
33
import { getThirdwebBaseUrl } from "../utils/domains.js";
44
import { getClientFetch } from "../utils/fetch.js";
55
import { stringify } from "../utils/json.js";
6+
import { BridgeApiError } from "./types/Errors.js";
67
import type { RouteStep } from "./types/Route.js";
78
import type { Token } from "./types/Token.js";
89

@@ -191,9 +192,12 @@ export async function prepare(
191192

192193
if (!response.ok) {
193194
const errorJson = await response.json();
194-
throw new Error(
195-
`${errorJson.code || response.status} | ${errorJson.message || response.statusText} - ${errorJson.correlationId || "N/A"}`,
196-
);
195+
throw new BridgeApiError({
196+
code: errorJson.code || "UNKNOWN_ERROR",
197+
message: errorJson.message || response.statusText,
198+
correlationId: errorJson.correlationId || undefined,
199+
statusCode: response.status,
200+
});
197201
}
198202

199203
const { data }: { data: OnrampPrepareQuoteResponseData } =

packages/thirdweb/src/bridge/OnrampStatus.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Hex as ox__Hex } from "ox";
22
import type { ThirdwebClient } from "../client/client.js";
33
import { getThirdwebBaseUrl } from "../utils/domains.js";
44
import { getClientFetch } from "../utils/fetch.js";
5+
import { BridgeApiError } from "./types/Errors.js";
56

67
/**
78
* Retrieves the status of an Onramp session created via {@link Bridge.Onramp.prepare}. The
@@ -72,9 +73,12 @@ export async function status(options: status.Options): Promise<status.Result> {
7273
const response = await clientFetch(url.toString());
7374
if (!response.ok) {
7475
const errorJson = await response.json();
75-
throw new Error(
76-
`${errorJson.code || response.status} | ${errorJson.message || response.statusText} - ${errorJson.correlationId || "N/A"}`,
77-
);
76+
throw new BridgeApiError({
77+
code: errorJson.code || "UNKNOWN_ERROR",
78+
message: errorJson.message || response.statusText,
79+
correlationId: errorJson.correlationId || undefined,
80+
statusCode: response.status,
81+
});
7882
}
7983

8084
const { data }: { data: status.Result } = await response.json();

packages/thirdweb/src/bridge/Routes.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Address as ox__Address, Hex as ox__Hex } from "ox";
22
import type { ThirdwebClient } from "../client/client.js";
33
import { getThirdwebBaseUrl } from "../utils/domains.js";
44
import { getClientFetch } from "../utils/fetch.js";
5+
import { BridgeApiError } from "./types/Errors.js";
56
import type { Route } from "./types/Route.js";
67

78
/**
@@ -162,7 +163,12 @@ export async function routes(options: routes.Options): Promise<routes.Result> {
162163
const response = await clientFetch(url.toString());
163164
if (!response.ok) {
164165
const errorJson = await response.json();
165-
throw new Error(`${errorJson.code} | ${errorJson.message}`);
166+
throw new BridgeApiError({
167+
code: errorJson.code || "UNKNOWN_ERROR",
168+
message: errorJson.message || response.statusText,
169+
correlationId: errorJson.correlationId || undefined,
170+
statusCode: response.status,
171+
});
166172
}
167173

168174
const { data }: { data: Route[] } = await response.json();

packages/thirdweb/src/bridge/Sell.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ThirdwebClient } from "../client/client.js";
44
import { getThirdwebBaseUrl } from "../utils/domains.js";
55
import { getClientFetch } from "../utils/fetch.js";
66
import { stringify } from "../utils/json.js";
7+
import { BridgeApiError } from "./types/Errors.js";
78
import type { PreparedQuote, Quote } from "./types/Quote.js";
89

910
/**
@@ -126,9 +127,12 @@ export async function quote(options: quote.Options): Promise<quote.Result> {
126127
const response = await clientFetch(url.toString());
127128
if (!response.ok) {
128129
const errorJson = await response.json();
129-
throw new Error(
130-
`${errorJson.code} | ${errorJson.message} - ${errorJson.correlationId}`,
131-
);
130+
throw new BridgeApiError({
131+
code: errorJson.code || "UNKNOWN_ERROR",
132+
message: errorJson.message || response.statusText,
133+
correlationId: errorJson.correlationId || undefined,
134+
statusCode: response.status,
135+
});
132136
}
133137

134138
const { data }: { data: Quote } = await response.json();
@@ -348,9 +352,12 @@ export async function prepare(
348352
});
349353
if (!response.ok) {
350354
const errorJson = await response.json();
351-
throw new Error(
352-
`${errorJson.code} | ${errorJson.message} - ${errorJson.correlationId}`,
353-
);
355+
throw new BridgeApiError({
356+
code: errorJson.code || "UNKNOWN_ERROR",
357+
message: errorJson.message || response.statusText,
358+
correlationId: errorJson.correlationId || undefined,
359+
statusCode: response.status,
360+
});
354361
}
355362

356363
const { data }: { data: PreparedQuote } = await response.json();

packages/thirdweb/src/bridge/Status.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Chain } from "../chains/types.js";
33
import type { ThirdwebClient } from "../client/client.js";
44
import { getThirdwebBaseUrl } from "../utils/domains.js";
55
import { getClientFetch } from "../utils/fetch.js";
6+
import { BridgeApiError } from "./types/Errors.js";
67
import type { Status } from "./types/Status.js";
78

89
/**
@@ -115,9 +116,12 @@ export async function status(options: status.Options): Promise<status.Result> {
115116
const response = await clientFetch(url.toString());
116117
if (!response.ok) {
117118
const errorJson = await response.json();
118-
throw new Error(
119-
`${errorJson.code} | ${errorJson.message} - ${errorJson.correlationId}`,
120-
);
119+
throw new BridgeApiError({
120+
code: errorJson.code || "UNKNOWN_ERROR",
121+
message: errorJson.message || response.statusText,
122+
correlationId: errorJson.correlationId || undefined,
123+
statusCode: response.status,
124+
});
121125
}
122126

123127
const { data }: { data: Status } = await response.json();

packages/thirdweb/src/bridge/Transfer.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ThirdwebClient } from "../client/client.js";
44
import { getThirdwebBaseUrl } from "../utils/domains.js";
55
import { getClientFetch } from "../utils/fetch.js";
66
import { stringify } from "../utils/json.js";
7+
import { BridgeApiError } from "./types/Errors.js";
78
import type { PreparedQuote } from "./types/Quote.js";
89

910
/**
@@ -212,9 +213,12 @@ export async function prepare(
212213
});
213214
if (!response.ok) {
214215
const errorJson = await response.json();
215-
throw new Error(
216-
`${errorJson.code} | ${errorJson.message} - ${errorJson.correlationId}`,
217-
);
216+
throw new BridgeApiError({
217+
code: errorJson.code || "UNKNOWN_ERROR",
218+
message: errorJson.message || response.statusText,
219+
correlationId: errorJson.correlationId || undefined,
220+
statusCode: response.status,
221+
});
218222
}
219223

220224
const { data }: { data: PreparedQuote } = await response.json();
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
type ErrorCode =
2+
| "INVALID_INPUT"
3+
| "ROUTE_NOT_FOUND"
4+
| "AMOUNT_TOO_LOW"
5+
| "AMOUNT_TOO_HIGH"
6+
| "UNKNOWN_ERROR";
7+
8+
export class BridgeApiError extends Error {
9+
code: ErrorCode;
10+
correlationId?: string;
11+
statusCode: number;
12+
13+
constructor(args: {
14+
code: ErrorCode;
15+
message: string;
16+
statusCode: number;
17+
correlationId?: string;
18+
}) {
19+
super(args.message);
20+
this.code = args.code;
21+
this.correlationId = args.correlationId;
22+
this.statusCode = args.statusCode;
23+
}
24+
}

packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/PayWIthCreditCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export function PayWithCreditCard(props: {
8585
{props.value
8686
? `${props.currency.symbol}${formatNumber(
8787
Number(props.value),
88-
6,
88+
2,
8989
)}`
9090
: "--"}
9191
</Text>

packages/thirdweb/src/react/web/utils/errors.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { BridgeApiError } from "../../../bridge/types/Errors.js";
2+
13
type ApiError = {
24
code: string;
35
title: string;
@@ -12,6 +14,14 @@ type ApiError = {
1214

1315
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
1416
export function getErrorMessage(err: any): ApiError {
17+
if (err instanceof BridgeApiError) {
18+
return {
19+
code: err.code,
20+
title: "Failed to Find Quote",
21+
message: getErrorMessageFromBridgeApiError(err),
22+
};
23+
}
24+
1525
if (typeof err.error === "object" && err.error.code) {
1626
if (err.error.code === "MINIMUM_PURCHASE_AMOUNT") {
1727
return {
@@ -29,6 +39,18 @@ export function getErrorMessage(err: any): ApiError {
2939
code: "UNABLE_TO_GET_PRICE_QUOTE",
3040
title: "Failed to Find Quote",
3141
message:
42+
err.message ||
3243
"We couldn't get a quote for this token pair. Select another token or pay with card.",
3344
};
3445
}
46+
47+
function getErrorMessageFromBridgeApiError(err: BridgeApiError) {
48+
let msg = err.message;
49+
if (msg.includes("Details")) {
50+
msg = msg.substring(0, msg.indexOf("Details"));
51+
}
52+
if (msg.includes("{")) {
53+
msg = msg.substring(0, msg.indexOf("{"));
54+
}
55+
return msg;
56+
}

0 commit comments

Comments
 (0)