Skip to content

Commit 49ae1e5

Browse files
implement retryWithBackoff for more network client methods
1 parent f5477b9 commit 49ae1e5

File tree

1 file changed

+71
-52
lines changed

1 file changed

+71
-52
lines changed

sdk/src/network-client.ts

Lines changed: 71 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -160,19 +160,27 @@ class AleoNetworkClient {
160160
* @param url
161161
*/
162162
async fetchRaw(url = "/"): Promise<string> {
163-
try {
164-
const response = await get(this.host + url, {
165-
headers: this.headers,
166-
});
167-
return await response.text();
168-
} catch (error) {
169-
throw new Error(`Error fetching data: ${error}`);
170-
}
171-
}
163+
try {
164+
return await retryWithBackoff(async () => {
165+
const response = await get(this.host + url, {
166+
headers: this.headers,
167+
});
168+
return await response.text();
169+
}, {
170+
retryOnStatus: [500, 502, 503, 504],
171+
shouldRetry: (err) => {
172+
const msg = err?.message?.toLowerCase?.() || "";
173+
return msg.includes("network") || msg.includes("timeout") || msg.includes("503");
174+
}
175+
});
176+
} catch (error) {
177+
throw new Error(`Error fetching data: ${error}`);
178+
}
179+
}
172180

173181

174182
/**
175-
* Wrapper around the POST helper to allow mocking in tests.
183+
* Wrapper around the POST helper to allow mocking in tests. Not meant for use in production.
176184
*
177185
* @param url The URL to POST to.
178186
* @param options The RequestInit options for the POST request.
@@ -383,25 +391,27 @@ class AleoNetworkClient {
383391
}
384392

385393
if (unspent) {
386-
// Otherwise record the nonce that has been found
387-
const serialNumber =
388-
recordPlaintext.serialNumberString(
389-
resolvedPrivateKey,
390-
"credits.aleo",
391-
"credits",
392-
);
393-
// Attempt to see if the serial number is spent
394-
try {
395-
await this.getTransitionId(
396-
serialNumber,
397-
);
398-
continue;
399-
} catch (error) {
400-
console.log(
401-
"Found unspent record!",
402-
);
403-
}
404-
}
394+
// Otherwise record the nonce that has been found
395+
const serialNumber = recordPlaintext.serialNumberString(
396+
resolvedPrivateKey,
397+
"credits.aleo",
398+
"credits",
399+
);
400+
// Attempt to see if the serial number is spent
401+
try {
402+
await retryWithBackoff(() => this.getTransitionId(serialNumber), {
403+
retryOnStatus: [500, 502, 503],
404+
shouldRetry: (err) => {
405+
const msg = err?.message?.toLowerCase?.() || "";
406+
return msg.includes("timeout") || msg.includes("503") || msg.includes("network");
407+
}
408+
});
409+
// If it succeeds, it means the record was spent → skip it
410+
continue;
411+
} catch (error) {
412+
console.log("Found unspent record!");
413+
}
414+
}
405415

406416
// Add the record to the list of records if the user did not specify amounts.
407417
if (!amounts) {
@@ -1433,29 +1443,38 @@ class AleoNetworkClient {
14331443
* @returns {Promise<string>} The solution id of the submitted solution or the resulting error.
14341444
*/
14351445
async submitSolution(solution: string): Promise<string> {
1436-
try {
1437-
const response = await post(this.host + "/solution/broadcast", {
1438-
body: solution,
1439-
headers: Object.assign({}, this.headers, {
1440-
"Content-Type": "application/json",
1441-
}),
1442-
});
1443-
1444-
try {
1445-
const text = await response.text();
1446-
return parseJSON(text);
1447-
} catch (error: any) {
1448-
throw new Error(
1449-
`Error posting transaction. Aleo network response: ${error.message}`,
1450-
);
1451-
}
1452-
} catch (error: any) {
1453-
throw new Error(
1454-
`Error posting transaction: No response received: ${error.message}`,
1455-
);
1456-
}
1457-
}
1458-
1446+
try {
1447+
const response = await retryWithBackoff(() =>
1448+
post(this.host + "/solution/broadcast", {
1449+
body: solution,
1450+
headers: Object.assign({}, this.headers, {
1451+
"Content-Type": "application/json",
1452+
}),
1453+
}),
1454+
{
1455+
// Only retry on network-level / transient errors to avoid duplicate submission
1456+
retryOnStatus: [500, 502, 503, 504],
1457+
shouldRetry: (err) => {
1458+
const msg = err?.message?.toLowerCase?.() || "";
1459+
return msg.includes("timeout") || msg.includes("network") || msg.includes("503");
1460+
},
1461+
}
1462+
);
1463+
1464+
try {
1465+
const text = await response.text();
1466+
return parseJSON(text);
1467+
} catch (error: any) {
1468+
throw new Error(
1469+
`Error posting solution. Aleo network response: ${error.message}`,
1470+
);
1471+
}
1472+
} catch (error: any) {
1473+
throw new Error(
1474+
`Error posting solution: No response received: ${error.message}`,
1475+
);
1476+
}
1477+
}
14591478
/**
14601479
* Await a submitted transaction to be confirmed or rejected on the Aleo network.
14611480
*

0 commit comments

Comments
 (0)