From c61db96980f83991aab7238a3d663b71cabc4b79 Mon Sep 17 00:00:00 2001 From: Amish Shah Date: Sat, 29 Apr 2017 20:00:05 +0100 Subject: [PATCH] sorry gus i borked --- src/client/rest/DiscordAPIError.js | 39 ++++++++++++ src/client/rest/RequestHandlers/Burst.js | 3 +- src/client/rest/RequestHandlers/Sequential.js | 60 +++++++++---------- src/util/Constants.js | 2 +- 4 files changed, 71 insertions(+), 33 deletions(-) create mode 100644 src/client/rest/DiscordAPIError.js diff --git a/src/client/rest/DiscordAPIError.js b/src/client/rest/DiscordAPIError.js new file mode 100644 index 000000000000..a6583681a8a8 --- /dev/null +++ b/src/client/rest/DiscordAPIError.js @@ -0,0 +1,39 @@ +/** + * Represents an error from the Discord API + */ +class DiscordAPIError extends Error { + constructor(error) { + super(); + const flattened = error.errors ? `\n${this.constructor.flattenErrors(error.errors).join('\n')}` : ''; + this.name = 'DiscordAPIError'; + this.message = `${error.message}${flattened}`; + + /** + * HTTP error code returned by Discord + * @type {number} + */ + this.code = error.code; + } + + /** + * Flattens an errors object returned from the API into an array + * @param {Object} obj Discord errors object + * @param {string} [key] idklol + * @returns {string[]} + */ + static flattenErrors(obj, key = '') { + let messages = []; + for (const k of Object.keys(obj)) { + const newKey = key ? isNaN(k) ? `${key}.${k}` : `${key}[${k}]` : k; + if (obj[k]._errors) { + messages.push(`${newKey}: ${obj[k]._errors.map(e => e.message).join(' ')}`); + } else { + messages = messages.concat(this.flattenErrors(obj[k], newKey)); + } + } + + return messages; + } +} + +module.exports = DiscordAPIError; diff --git a/src/client/rest/RequestHandlers/Burst.js b/src/client/rest/RequestHandlers/Burst.js index dd33a4b52331..e5a160246897 100644 --- a/src/client/rest/RequestHandlers/Burst.js +++ b/src/client/rest/RequestHandlers/Burst.js @@ -1,4 +1,5 @@ const RequestHandler = require('./RequestHandler'); +const DiscordAPIError = require('../DiscordAPIError'); class BurstRequestHandler extends RequestHandler { constructor(restManager, endpoint) { @@ -40,7 +41,7 @@ class BurstRequestHandler extends RequestHandler { this.resetTimeout = null; }, Number(res.headers['retry-after']) + this.client.options.restTimeOffset); } else { - item.reject(err); + item.reject(err.status === 400 ? new DiscordAPIError(res.body) : err); this.handle(); } } else { diff --git a/src/client/rest/RequestHandlers/Sequential.js b/src/client/rest/RequestHandlers/Sequential.js index d5a3a8c14836..9ba3c9ebb440 100644 --- a/src/client/rest/RequestHandlers/Sequential.js +++ b/src/client/rest/RequestHandlers/Sequential.js @@ -1,4 +1,5 @@ const RequestHandler = require('./RequestHandler'); +const DiscordAPIError = require('../DiscordAPIError'); /** * Handles API Requests sequentially, i.e. we wait until the current request is finished before moving onto @@ -48,42 +49,39 @@ class SequentialRequestHandler extends RequestHandler { execute(item) { this.busy = true; return new Promise(resolve => { - item.request - .gen() - .on('error', e => item.reject(e)) - .end((err, res) => { - if (res && res.headers) { - this.requestLimit = Number(res.headers['x-ratelimit-limit']); - this.requestResetTime = Number(res.headers['x-ratelimit-reset']) * 1000; - this.requestRemaining = Number(res.headers['x-ratelimit-remaining']); - this.timeDifference = Date.now() - new Date(res.headers.date).getTime(); - } - if (err) { - if (err.status === 429) { - this.queue.unshift(item); - this.restManager.client.setTimeout(() => { - this.globalLimit = false; - resolve(); - }, Number(res.headers['retry-after']) + this.restManager.client.options.restTimeOffset); - if (res.headers['x-ratelimit-global']) this.globalLimit = true; - } else { - item.reject(err); - resolve(err); - } + item.request.gen().end((err, res) => { + if (res && res.headers) { + this.requestLimit = Number(res.headers['x-ratelimit-limit']); + this.requestResetTime = Number(res.headers['x-ratelimit-reset']) * 1000; + this.requestRemaining = Number(res.headers['x-ratelimit-remaining']); + this.timeDifference = Date.now() - new Date(res.headers.date).getTime(); + } + if (err) { + if (err.status === 429) { + this.queue.unshift(item); + this.restManager.client.setTimeout(() => { + this.globalLimit = false; + resolve(); + }, Number(res.headers['retry-after']) + this.restManager.client.options.restTimeOffset); + if (res.headers['x-ratelimit-global']) this.globalLimit = true; } else { - this.globalLimit = false; - const data = res && res.body ? res.body : {}; - item.resolve(data); - if (this.requestRemaining === 0) { - this.restManager.client.setTimeout( + item.reject(err.status === 400 ? new DiscordAPIError(res.body) : err); + resolve(err); + } + } else { + this.globalLimit = false; + const data = res && res.body ? res.body : {}; + item.resolve(data); + if (this.requestRemaining === 0) { + this.restManager.client.setTimeout( () => resolve(data), this.requestResetTime - Date.now() + this.timeDifference + this.restManager.client.options.restTimeOffset ); - } else { - resolve(data); - } + } else { + resolve(data); } - }); + } + }); }); } diff --git a/src/util/Constants.js b/src/util/Constants.js index dbd69337f112..fbd8538da3f4 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -64,7 +64,7 @@ exports.DefaultOptions = { version: 6, }, http: { - version: 6, + version: 7, host: 'https://discordapp.com', cdn: 'https://cdn.discordapp.com', },