diff --git a/src/client/Client.js b/src/client/Client.js index f3a6617d5..e285b9237 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -436,6 +436,9 @@ class Client extends BaseClient { if (!(options.disabledEvents instanceof Array)) { throw new TypeError('CLIENT_INVALID_OPTION', 'disabledEvents', 'an Array'); } + if (typeof options.retryLimit !== 'number' || isNaN(options.retryLimit)) { + throw new TypeError('CLIENT_INVALID_OPTION', 'retryLimit', 'a number'); + } } } diff --git a/src/rest/RESTManager.js b/src/rest/RESTManager.js index 3d42b0b0e..53a8047f5 100644 --- a/src/rest/RESTManager.js +++ b/src/rest/RESTManager.js @@ -41,6 +41,7 @@ class RESTManager { request: apiRequest, resolve, reject, + retries: 0, }).catch(reject); }); } diff --git a/src/rest/RequestHandler.js b/src/rest/RequestHandler.js index c6ea73ba5..99595b4b1 100644 --- a/src/rest/RequestHandler.js +++ b/src/rest/RequestHandler.js @@ -150,13 +150,13 @@ class RequestHandler { await Util.delayFor(this.retryAfter); return this.run(); } else if (res.status >= 500 && res.status < 600) { - // Retry once for possible serverside issues - if (item.retried) { + // Retry the specified number of times for possible serverside issues + if (item.retries === this.manager.client.options.retryLimit) { return reject( new HTTPError(res.statusText, res.constructor.name, res.status, item.request.method, request.route) ); } else { - item.retried = true; + item.retries++; this.queue.unshift(item); return this.run(); } diff --git a/src/util/Constants.js b/src/util/Constants.js index b2e02c3ab..c4ab29a93 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -23,6 +23,7 @@ const browser = exports.browser = typeof window !== 'undefined'; * requests (higher values will reduce rate-limiting errors on bad connections) * @property {number} [restSweepInterval=60] How frequently to delete inactive request buckets, in seconds * (or 0 for never) + * @property {number} [retryLimit=1] How many times to retry on 5XX errors (Infinity for indefinite amount of retries) * @property {PresenceData} [presence] Presence data to use upon login * @property {WSEventType[]} [disabledEvents] An array of disabled websocket events. Events in this array will not be * processed, potentially resulting in performance improvements for larger bots. Only disable events you are @@ -42,6 +43,7 @@ exports.DefaultOptions = { disableEveryone: false, restWsBridgeTimeout: 5000, disabledEvents: [], + retryLimit: 1, restTimeOffset: 500, restSweepInterval: 60, presence: {}, diff --git a/typings/index.d.ts b/typings/index.d.ts index 322691241..12f38f31e 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1557,6 +1557,7 @@ declare module 'discord.js' { disableEveryone?: boolean; restWsBridgeTimeout?: number; restTimeOffset?: number; + retryLimit?: number, disabledEvents?: WSEventType[]; ws?: WebSocketOptions; http?: HTTPOptions;