diff --git a/docs/generated/changelog.html b/docs/generated/changelog.html
index 8d8cf012b..0581bc387 100644
--- a/docs/generated/changelog.html
+++ b/docs/generated/changelog.html
@@ -12,6 +12,7 @@
Agent-JS Changelog
Version x.x.x
+ - feat: retry logic will catch and retry for thrown errors
-
feat!: adds certificate logic to decode subnet and node key paths from the hashtree.
Changes the interface for `lookup_path` to allow returning a HashTree, but also constrains
diff --git a/packages/agent/src/agent/http/http.test.ts b/packages/agent/src/agent/http/http.test.ts
index 1df6284c7..d0c12ec86 100644
--- a/packages/agent/src/agent/http/http.test.ts
+++ b/packages/agent/src/agent/http/http.test.ts
@@ -811,3 +811,20 @@ describe('default host', () => {
}
});
});
+
+test('retry requests that fail due to a network failure', async () => {
+ const mockFetch: jest.Mock = jest.fn(() => {
+ throw new Error('Network failure');
+ });
+
+ const agent = new HttpAgent({ host: HTTP_AGENT_HOST, fetch: mockFetch });
+ try {
+ await agent.call(Principal.managementCanister(), {
+ methodName: 'test',
+ arg: new Uint8Array().buffer,
+ });
+ } catch (error) {
+ // One try + three retries
+ expect(mockFetch.mock.calls.length).toBe(4);
+ }
+});
diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts
index 48fef4935..0e4df3a04 100644
--- a/packages/agent/src/agent/http/index.ts
+++ b/packages/agent/src/agent/http/index.ts
@@ -365,7 +365,20 @@ export class HttpAgent implements Agent {
}
private async _requestAndRetry(request: () => Promise, tries = 0): Promise {
- const response = await request();
+ let response: Response;
+ try {
+ response = await request();
+ } catch (error) {
+ if (this._retryTimes > tries) {
+ console.warn(
+ `Caught exception while attempting to make request:\n` +
+ ` ${error}\n` +
+ ` Retrying request.`,
+ );
+ return await this._requestAndRetry(request, tries + 1);
+ }
+ throw error;
+ }
if (response.ok) {
return response;
}