diff --git a/docs/classes/google-spreadsheet.md b/docs/classes/google-spreadsheet.md index 55553fb..ac7591b 100644 --- a/docs/classes/google-spreadsheet.md +++ b/docs/classes/google-spreadsheet.md @@ -210,3 +210,13 @@ Param|Type|Required|Description `rangeId`|String|✅|ID of the range to remove +### Retry logic + +### `setRetryOptions(metadataId)` (async) :id=fn-setRetryOptions +> Set the retry options for when your requests are rate-limited (error 429) +> If these options are not set then requests won't be retried + +Param|Type|Required|Description +---|---|---|--- +`retries`|Number|✅|The number of times a request should be retried +`retryDelay`|Number|✅|The time to delay in miliseconds between retry attempts diff --git a/lib/GoogleSpreadsheet.js b/lib/GoogleSpreadsheet.js index 98d3a19..742df5e 100644 --- a/lib/GoogleSpreadsheet.js +++ b/lib/GoogleSpreadsheet.js @@ -57,6 +57,9 @@ class GoogleSpreadsheet { this._handleAxiosErrors.bind(this) ); + this._retries = 0; + this._retryDelay = 3000; + return this; } @@ -122,6 +125,11 @@ class GoogleSpreadsheet { */ } + setRetryOptions(retries, retryDelay) { + this._retries = retries; + this._retryDelay = retryDelay; + } + // TODO: provide mechanism to share single JWT auth between docs? // INTERNAL UTILITY FUNCTIONS //////////////////////////////////////////////////////////////////// @@ -150,7 +158,21 @@ class GoogleSpreadsheet { async _handleAxiosResponse(response) { return response; } async _handleAxiosErrors(error) { - // console.log(error); + if (_.get(error, 'response.status') === 429) { + const config = error.config; + const retryCount = config.retryCount || 0; + + if (this._retries > 0 && retryCount < this._retries) { + config.retryCount = retryCount + 1; + + return new Promise((resolve) => { + setTimeout(() => { + resolve(this.axios(config)); + }, this._retryDelay); + }); + } + } + if (error.response && error.response.data) { // usually the error has a code and message, but occasionally not if (!error.response.data.error) throw error;