Skip to content

Commit

Permalink
Automatically retry http request errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
wparad committed Jan 30, 2023
1 parent a2457d2 commit 0f272c6
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This is the changelog for [Authress SDK](readme.md).
## 2.0 ##
* Enable passing just the access token as a string to `AuthressClient`.
* Fix the issuer path for service client tokens to include the accountId when the custom domain is not specified. The default issuer is converted from `api.authress.io` to `accountId.api.authress.io`. if this fallback issuer domain was specified in your authorizer, upgrading this library without changing your defined issuer, which prevent future access.
* Add automatic retries to all requests.

## 1.3 ##
* Add new `Pagination` type which pagination `next.cursor` to enable paging through resources.
Expand Down
52 changes: 40 additions & 12 deletions src/httpClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ const defaultHeaders = {
'Content-Type': 'application/json'
};

async function retryExecutor(func) {
let lastError = null;
for (let iteration = 0; iteration < 5; iteration++) {
try {
const result = await func();
return result;
} catch (error) {
lastError = error;
if (error.code === 'EPIPE' || error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT' || error.code === 'ECONNRESET' || error.status >= 500) {
await new Promise(resolve => setTimeout(resolve, 10 * 2 ** iteration));
continue;
}
throw error;
}
}
throw lastError;
}

class HttpClient {
constructor(baseUrl, tokenProvider) {
this.baseUrl = new URL(`https://${baseUrl.replace(/^(https?:\/\/)/, '')}`).toString().replace(/\/$/, '');
Expand Down Expand Up @@ -65,34 +83,44 @@ class HttpClient {
}

get(url, headers, type = 'json') {
return this.client.get(url.toString(), {
headers: Object.assign({}, defaultHeaders, headers),
responseType: type
return retryExecutor(() => {
return this.client.get(url.toString(), {
headers: Object.assign({}, defaultHeaders, headers),
responseType: type
});
});
}

delete(url, headers, type = 'json') {
return this.client.delete(url.toString(), {
headers: Object.assign({}, defaultHeaders, headers),
responseType: type
return retryExecutor(() => {
return this.client.delete(url.toString(), {
headers: Object.assign({}, defaultHeaders, headers),
responseType: type
});
});
}

post(url, data, headers) {
return this.client.post(url.toString(), data, {
headers: Object.assign({}, defaultHeaders, headers)
return retryExecutor(() => {
return this.client.post(url.toString(), data, {
headers: Object.assign({}, defaultHeaders, headers)
});
});
}

put(url, data, headers) {
return this.client.put(url.toString(), data, {
headers: Object.assign({}, defaultHeaders, headers)
return retryExecutor(() => {
return this.client.put(url.toString(), data, {
headers: Object.assign({}, defaultHeaders, headers)
});
});
}

patch(url, data, headers) {
return this.client.patch(url.toString(), data, {
headers: Object.assign({}, defaultHeaders, headers)
return retryExecutor(() => {
return this.client.patch(url.toString(), data, {
headers: Object.assign({}, defaultHeaders, headers)
});
});
}
}
Expand Down

0 comments on commit 0f272c6

Please sign in to comment.