From ee1d4c53f2770b5e4748d0d7402dc0291f9f869e Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Tue, 24 Oct 2017 15:07:21 -0500 Subject: [PATCH] Add rateLimit event (#2019) * add ratelimited event * add some useful props * death * more death * Update tester1000.js * Update RequestHandler.js --- src/rest/handlers/RequestHandler.js | 33 ++++++++++++++++++++++++++--- src/rest/handlers/burst.js | 2 +- src/rest/handlers/sequential.js | 2 +- src/util/Constants.js | 1 + test/tester1000.js | 1 + 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/rest/handlers/RequestHandler.js b/src/rest/handlers/RequestHandler.js index d1dea22e3..aaeed9d69 100644 --- a/src/rest/handlers/RequestHandler.js +++ b/src/rest/handlers/RequestHandler.js @@ -1,4 +1,5 @@ const DiscordAPIError = require('../DiscordAPIError'); +const { Events: { RATE_LIMIT } } = require('../../util/Constants'); class RequestHandler { constructor(manager, handler) { @@ -29,9 +30,35 @@ class RequestHandler { execute(item) { return new Promise((resolve, reject) => { const finish = timeout => { - // eslint-disable-next-line prefer-promise-reject-errors - if (timeout || this.limited) reject({ timeout, limited: this.limited }); - else resolve(); + if (timeout || this.limited) { + if (!timeout) { + timeout = this.resetTime - Date.now() + this.timeDifference + this.client.options.restTimeOffset; + } + // eslint-disable-next-line prefer-promise-reject-errors + reject({ timeout }); + if (this.client.listenerCount(RATE_LIMIT)) { + /** + * Emitted when the client hits a rate limit while making a request + * @event Client#rateLimit + * @prop {number} timeout Timeout in ms + * @prop {number} limit Number of requests that can be made to this endpoint + * @prop {number} timeDifference Delta-T in ms between your system and Discord servers + * @prop {string} method HTTP method used for request that triggered this event + * @prop {string} path Path used for request that triggered this event + * @prop {string} route Route used for request that triggered this event + */ + this.client.emit(RATE_LIMIT, { + timeout, + limit: this.limit, + timeDifference: this.timeDifference, + method: item.request.method, + path: item.request.path, + route: item.request.route, + }); + } + } else { + resolve(); + } }; item.request.gen().end((err, res) => { if (res && res.headers) { diff --git a/src/rest/handlers/burst.js b/src/rest/handlers/burst.js index 8184d1037..fe35d20ae 100644 --- a/src/rest/handlers/burst.js +++ b/src/rest/handlers/burst.js @@ -6,7 +6,7 @@ module.exports = function burst() { this.client.setTimeout(() => { this.reset(); this.handle(); - }, timeout || (this.resetTime - Date.now() + this.timeDifference + this.client.options.restTimeOffset)); + }, timeout); }); this.remaining--; this.handle(); diff --git a/src/rest/handlers/sequential.js b/src/rest/handlers/sequential.js index efc10b058..17e368036 100644 --- a/src/rest/handlers/sequential.js +++ b/src/rest/handlers/sequential.js @@ -11,6 +11,6 @@ module.exports = function sequential() { this.reset(); this.busy = false; this.handle(); - }, timeout || (this.resetTime - Date.now() + this.timeDifference + this.client.options.restTimeOffset)); + }, timeout); }); }; diff --git a/src/util/Constants.js b/src/util/Constants.js index 07273a130..3c54dd638 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -194,6 +194,7 @@ exports.VoiceOPCodes = { }; exports.Events = { + RATE_LIMIT: 'rateLimit', READY: 'ready', RESUMED: 'resumed', GUILD_CREATE: 'guildCreate', diff --git a/test/tester1000.js b/test/tester1000.js index e884324b4..99209c71a 100644 --- a/test/tester1000.js +++ b/test/tester1000.js @@ -10,6 +10,7 @@ client.on('debug', log); client.on('ready', () => { log('READY', client.user.tag, client.user.id); }); +client.on('rateLimit', log); const commands = { eval: message => {