From 6339ac16f6d4026fa0dd38dc86ccb38782eb054d Mon Sep 17 00:00:00 2001 From: Vlad Frangu Date: Sat, 29 May 2021 19:32:48 +0300 Subject: [PATCH 1/3] feat(Rest): show the data that is sent to Discord when an errors occurs Now you know what Discord means by your embed being wrong... --- src/rest/DiscordAPIError.js | 15 ++++++++++++--- src/rest/HTTPError.js | 29 ++++++++++++++++++++++++++--- src/rest/RequestHandler.js | 8 ++++---- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/rest/DiscordAPIError.js b/src/rest/DiscordAPIError.js index aebe513d0e19..fa54546b1604 100644 --- a/src/rest/DiscordAPIError.js +++ b/src/rest/DiscordAPIError.js @@ -5,7 +5,7 @@ * @extends Error */ class DiscordAPIError extends Error { - constructor(path, error, method, status) { + constructor(error, status, request) { super(); const flattened = this.constructor.flattenErrors(error.errors || error).join('\n'); this.name = 'DiscordAPIError'; @@ -15,13 +15,13 @@ class DiscordAPIError extends Error { * The HTTP method used for the request * @type {string} */ - this.method = method; + this.method = request.method; /** * The path of the request relative to the HTTP endpoint * @type {string} */ - this.path = path; + this.path = request.path; /** * HTTP error code returned by Discord @@ -34,6 +34,15 @@ class DiscordAPIError extends Error { * @type {number} */ this.httpStatus = status; + + /** + * The data associated with the request that caused this error + * @type {HTTPErrorData} + */ + this.requestData = { + jsonData: request.options.data, + files: request.options.files ?? [], + }; } /** diff --git a/src/rest/HTTPError.js b/src/rest/HTTPError.js index 2911467fcdfd..18bbbd235c58 100644 --- a/src/rest/HTTPError.js +++ b/src/rest/HTTPError.js @@ -5,7 +5,7 @@ * @extends Error */ class HTTPError extends Error { - constructor(message, name, code, method, path) { + constructor(message, name, code, request) { super(message); /** @@ -24,13 +24,36 @@ class HTTPError extends Error { * The HTTP method used for the request * @type {string} */ - this.method = method; + this.method = request.method; /** * The path of the request relative to the HTTP endpoint * @type {string} */ - this.path = path; + this.path = request.path; + + /** + * The HTTP data that was sent to Discord + * @typedef {Object} HTTPErrorData + * @property {*} jsonData The JSON data that was sent + * @property {HTTPAttachmentData[]} files The files that were sent with this request, if any + */ + + /** + * The attachment data that is sent to Discord + * @typedef {Object} HTTPAttachmentData + * @property {string} name The file name + * @property {Buffer} file The file buffer + */ + + /** + * The data associated with the request that caused this error + * @type {HTTPErrorData} + */ + this.requestData = { + jsonData: request.options.data, + files: request.options.files ?? [], + }; } } diff --git a/src/rest/RequestHandler.js b/src/rest/RequestHandler.js index 2b76ecf2c416..1c27a172a28f 100644 --- a/src/rest/RequestHandler.js +++ b/src/rest/RequestHandler.js @@ -143,7 +143,7 @@ class RequestHandler { } catch (error) { // Retry the specified number of times for request abortions if (request.retries === this.manager.client.options.retryLimit) { - throw new HTTPError(error.message, error.constructor.name, error.status, request.method, request.path); + throw new HTTPError(error.message, error.constructor.name, error.status, request); } request.retries++; @@ -237,17 +237,17 @@ class RequestHandler { try { data = await parseResponse(res); } catch (err) { - throw new HTTPError(err.message, err.constructor.name, err.status, request.method, request.path); + throw new HTTPError(err.message, err.constructor.name, err.status, request); } - throw new DiscordAPIError(request.path, data, request.method, res.status); + throw new DiscordAPIError(data, res.status, request); } // Handle 5xx responses if (res.status >= 500 && res.status < 600) { // Retry the specified number of times for possible serverside issues if (request.retries === this.manager.client.options.retryLimit) { - throw new HTTPError(res.statusText, res.constructor.name, res.status, request.method, request.path); + throw new HTTPError(res.statusText, res.constructor.name, res.status, request); } request.retries++; From 361f3380a4fff10800199e5c4fce2997e7ed2c39 Mon Sep 17 00:00:00 2001 From: Vlad Frangu Date: Sat, 29 May 2021 19:35:45 +0300 Subject: [PATCH 2/3] fix(APIMessage): don't send embeds for non-webhook requests --- src/rest/DiscordAPIError.js | 2 +- src/rest/HTTPError.js | 4 ++-- src/structures/APIMessage.js | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/rest/DiscordAPIError.js b/src/rest/DiscordAPIError.js index fa54546b1604..af060da30c4b 100644 --- a/src/rest/DiscordAPIError.js +++ b/src/rest/DiscordAPIError.js @@ -40,7 +40,7 @@ class DiscordAPIError extends Error { * @type {HTTPErrorData} */ this.requestData = { - jsonData: request.options.data, + json: request.options.data, files: request.options.files ?? [], }; } diff --git a/src/rest/HTTPError.js b/src/rest/HTTPError.js index 18bbbd235c58..8613cd947529 100644 --- a/src/rest/HTTPError.js +++ b/src/rest/HTTPError.js @@ -35,7 +35,7 @@ class HTTPError extends Error { /** * The HTTP data that was sent to Discord * @typedef {Object} HTTPErrorData - * @property {*} jsonData The JSON data that was sent + * @property {*} json The JSON data that was sent * @property {HTTPAttachmentData[]} files The files that were sent with this request, if any */ @@ -51,7 +51,7 @@ class HTTPError extends Error { * @type {HTTPErrorData} */ this.requestData = { - jsonData: request.options.data, + json: request.options.data, files: request.options.files ?? [], }; } diff --git a/src/structures/APIMessage.js b/src/structures/APIMessage.js index c3bcfab32d8c..41989ecf1788 100644 --- a/src/structures/APIMessage.js +++ b/src/structures/APIMessage.js @@ -125,6 +125,7 @@ class APIMessage { */ resolveData() { if (this.data) return this; + const isWebhook = this.isWebhook; const content = this.makeContent(); const tts = Boolean(this.options.tts); @@ -139,7 +140,7 @@ class APIMessage { } const embedLikes = []; - if (this.isInteraction || this.isWebhook) { + if (this.isInteraction || isWebhook) { if (this.options.embeds) { embedLikes.push(...this.options.embeds); } @@ -150,7 +151,7 @@ class APIMessage { let username; let avatarURL; - if (this.isWebhook) { + if (isWebhook) { username = this.options.username || this.target.name; if (this.options.avatarURL) avatarURL = this.options.avatarURL; } @@ -192,7 +193,7 @@ class APIMessage { tts, nonce, embed: this.options.embed === null ? null : embeds[0], - embeds, + embeds: isWebhook ? embeds : undefined, username, avatar_url: avatarURL, allowed_mentions: From aedc4ffb69a917ec4d40c23382ae827b25ac33f2 Mon Sep 17 00:00:00 2001 From: Vlad Frangu Date: Wed, 2 Jun 2021 21:59:20 +0300 Subject: [PATCH 3/3] fix: include `embeds` if it's an interaction --- src/structures/APIMessage.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/structures/APIMessage.js b/src/structures/APIMessage.js index 41989ecf1788..56840bd6205f 100644 --- a/src/structures/APIMessage.js +++ b/src/structures/APIMessage.js @@ -125,7 +125,9 @@ class APIMessage { */ resolveData() { if (this.data) return this; + const isInteraction = this.isInteraction; const isWebhook = this.isWebhook; + const isWebhookLike = isInteraction || isWebhook; const content = this.makeContent(); const tts = Boolean(this.options.tts); @@ -140,7 +142,7 @@ class APIMessage { } const embedLikes = []; - if (this.isInteraction || isWebhook) { + if (isWebhookLike) { if (this.options.embeds) { embedLikes.push(...this.options.embeds); } @@ -160,7 +162,7 @@ class APIMessage { if (this.isMessage) { // eslint-disable-next-line eqeqeq flags = this.options.flags != null ? new MessageFlags(this.options.flags).bitfield : this.target.flags.bitfield; - } else if (this.isInteraction && this.options.ephemeral) { + } else if (isInteraction && this.options.ephemeral) { flags = MessageFlags.FLAGS.EPHEMERAL; } @@ -192,8 +194,8 @@ class APIMessage { content, tts, nonce, - embed: this.options.embed === null ? null : embeds[0], - embeds: isWebhook ? embeds : undefined, + embed: !isWebhookLike ? (this.options.embed === null ? null : embeds[0]) : undefined, + embeds: isWebhookLike ? embeds : undefined, username, avatar_url: avatarURL, allowed_mentions: