mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
refactor: errors (#8068)
Co-authored-by: Parbez <imranbarbhuiya.fsd@gmail.com> Co-authored-by: A. Román <kyradiscord@gmail.com> Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
const EventEmitter = require('node:events');
|
||||
const { REST } = require('@discordjs/rest');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const Options = require('../util/Options');
|
||||
const { mergeDefault, flatten } = require('../util/Util');
|
||||
|
||||
@@ -15,7 +15,7 @@ class BaseClient extends EventEmitter {
|
||||
super({ captureRejections: true });
|
||||
|
||||
if (typeof options !== 'object' || options === null) {
|
||||
throw new TypeError('INVALID_TYPE', 'options', 'object', true);
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,7 @@ const BaseClient = require('./BaseClient');
|
||||
const ActionsManager = require('./actions/ActionsManager');
|
||||
const ClientVoiceManager = require('./voice/ClientVoiceManager');
|
||||
const WebSocketManager = require('./websocket/WebSocketManager');
|
||||
const { Error, TypeError, RangeError } = require('../errors');
|
||||
const { Error, TypeError, RangeError, ErrorCodes } = require('../errors');
|
||||
const BaseGuildEmojiManager = require('../managers/BaseGuildEmojiManager');
|
||||
const ChannelManager = require('../managers/ChannelManager');
|
||||
const GuildManager = require('../managers/GuildManager');
|
||||
@@ -211,7 +211,7 @@ class Client extends BaseClient {
|
||||
* client.login('my token');
|
||||
*/
|
||||
async login(token = this.token) {
|
||||
if (!token || typeof token !== 'string') throw new Error('TOKEN_INVALID');
|
||||
if (!token || typeof token !== 'string') throw new Error(ErrorCodes.TokenInvalid);
|
||||
this.token = token = token.replace(/^(Bot|Bearer)\s*/i, '');
|
||||
this.rest.setToken(token);
|
||||
this.emit(
|
||||
@@ -366,7 +366,7 @@ class Client extends BaseClient {
|
||||
*/
|
||||
async fetchGuildPreview(guild) {
|
||||
const id = this.guilds.resolveId(guild);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'guild', 'GuildResolvable');
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'guild', 'GuildResolvable');
|
||||
const data = await this.rest.get(Routes.guildPreview(id));
|
||||
return new GuildPreview(this, data);
|
||||
}
|
||||
@@ -378,7 +378,7 @@ class Client extends BaseClient {
|
||||
*/
|
||||
async fetchGuildWidget(guild) {
|
||||
const id = this.guilds.resolveId(guild);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'guild', 'GuildResolvable');
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'guild', 'GuildResolvable');
|
||||
const data = await this.rest.get(Routes.guildWidgetJSON(id));
|
||||
return new Widget(this, data);
|
||||
}
|
||||
@@ -413,23 +413,23 @@ class Client extends BaseClient {
|
||||
* console.log(`Generated bot invite link: ${link}`);
|
||||
*/
|
||||
generateInvite(options = {}) {
|
||||
if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true);
|
||||
if (!this.application) throw new Error('CLIENT_NOT_READY', 'generate an invite link');
|
||||
if (typeof options !== 'object') throw new TypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
||||
if (!this.application) throw new Error(ErrorCodes.ClientNotReady, 'generate an invite link');
|
||||
|
||||
const { scopes } = options;
|
||||
if (typeof scopes === 'undefined') {
|
||||
throw new TypeError('INVITE_MISSING_SCOPES');
|
||||
throw new TypeError(ErrorCodes.InvalidMissingScopes);
|
||||
}
|
||||
if (!Array.isArray(scopes)) {
|
||||
throw new TypeError('INVALID_TYPE', 'scopes', 'Array of Invite Scopes', true);
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'scopes', 'Array of Invite Scopes', true);
|
||||
}
|
||||
if (!scopes.some(scope => [OAuth2Scopes.Bot, OAuth2Scopes.ApplicationsCommands].includes(scope))) {
|
||||
throw new TypeError('INVITE_MISSING_SCOPES');
|
||||
throw new TypeError(ErrorCodes.InvalidMissingScopes);
|
||||
}
|
||||
const validScopes = Object.values(OAuth2Scopes);
|
||||
const invalidScope = scopes.find(scope => !validScopes.includes(scope));
|
||||
if (invalidScope) {
|
||||
throw new TypeError('INVALID_ELEMENT', 'Array', 'scopes', invalidScope);
|
||||
throw new TypeError(ErrorCodes.InvalidElement, 'Array', 'scopes', invalidScope);
|
||||
}
|
||||
|
||||
const query = makeURLSearchParams({
|
||||
@@ -445,7 +445,7 @@ class Client extends BaseClient {
|
||||
|
||||
if (options.guild) {
|
||||
const guildId = this.guilds.resolveId(options.guild);
|
||||
if (!guildId) throw new TypeError('INVALID_TYPE', 'options.guild', 'GuildResolvable');
|
||||
if (!guildId) throw new TypeError(ErrorCodes.InvalidType, 'options.guild', 'GuildResolvable');
|
||||
query.set('guild_id', guildId);
|
||||
}
|
||||
|
||||
@@ -476,31 +476,31 @@ class Client extends BaseClient {
|
||||
*/
|
||||
_validateOptions(options = this.options) {
|
||||
if (typeof options.intents === 'undefined') {
|
||||
throw new TypeError('CLIENT_MISSING_INTENTS');
|
||||
throw new TypeError(ErrorCodes.ClientMissingIntents);
|
||||
} else {
|
||||
options.intents = IntentsBitField.resolve(options.intents);
|
||||
}
|
||||
if (typeof options.shardCount !== 'number' || isNaN(options.shardCount) || options.shardCount < 1) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'shardCount', 'a number greater than or equal to 1');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'shardCount', 'a number greater than or equal to 1');
|
||||
}
|
||||
if (options.shards && !(options.shards === 'auto' || Array.isArray(options.shards))) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'shards', "'auto', a number or array of numbers");
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'shards', "'auto', a number or array of numbers");
|
||||
}
|
||||
if (options.shards && !options.shards.length) throw new RangeError('CLIENT_INVALID_PROVIDED_SHARDS');
|
||||
if (options.shards && !options.shards.length) throw new RangeError(ErrorCodes.ClientInvalidProvidedShards);
|
||||
if (typeof options.makeCache !== 'function') {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'makeCache', 'a function');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'makeCache', 'a function');
|
||||
}
|
||||
if (typeof options.sweepers !== 'object' || options.sweepers === null) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'sweepers', 'an object');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'sweepers', 'an object');
|
||||
}
|
||||
if (!Array.isArray(options.partials)) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'partials', 'an Array');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'partials', 'an Array');
|
||||
}
|
||||
if (typeof options.waitGuildTimeout !== 'number' || isNaN(options.waitGuildTimeout)) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'waitGuildTimeout', 'a number');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'waitGuildTimeout', 'a number');
|
||||
}
|
||||
if (typeof options.failIfNotExists !== 'boolean') {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'failIfNotExists', 'a boolean');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'failIfNotExists', 'a boolean');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const BaseClient = require('./BaseClient');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const Webhook = require('../structures/Webhook');
|
||||
|
||||
/**
|
||||
@@ -33,7 +33,7 @@ class WebhookClient extends BaseClient {
|
||||
/https?:\/\/(?:ptb\.|canary\.)?discord\.com\/api(?:\/v\d{1,2})?\/webhooks\/(\d{17,19})\/([\w-]{68})/i,
|
||||
);
|
||||
|
||||
if (!url || url.length <= 1) throw new Error('WEBHOOK_URL_INVALID');
|
||||
if (!url || url.length <= 1) throw new Error(ErrorCodes.WebhookURLInvalid);
|
||||
|
||||
[, id, token] = url;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ const { Collection } = require('@discordjs/collection');
|
||||
const { GatewayCloseCodes, GatewayDispatchEvents, Routes } = require('discord-api-types/v10');
|
||||
const WebSocketShard = require('./WebSocketShard');
|
||||
const PacketHandlers = require('./handlers');
|
||||
const { Error } = require('../../errors');
|
||||
const { Error, ErrorCodes } = require('../../errors');
|
||||
const Events = require('../../util/Events');
|
||||
const ShardEvents = require('../../util/ShardEvents');
|
||||
const Status = require('../../util/Status');
|
||||
@@ -130,7 +130,7 @@ class WebSocketManager extends EventEmitter {
|
||||
* @private
|
||||
*/
|
||||
async connect() {
|
||||
const invalidToken = new Error(GatewayCloseCodes[GatewayCloseCodes.AuthenticationFailed]);
|
||||
const invalidToken = new Error(ErrorCodes.AuthenticationFailed);
|
||||
const {
|
||||
url: gatewayURL,
|
||||
shards: recommendedShards,
|
||||
@@ -318,7 +318,8 @@ class WebSocketManager extends EventEmitter {
|
||||
*/
|
||||
destroy() {
|
||||
if (this.destroyed) return;
|
||||
this.debug(`Manager was destroyed. Called by:\n${new Error('MANAGER_DESTROYED').stack}`);
|
||||
// TODO: Make a util for getting a stack
|
||||
this.debug(`Manager was destroyed. Called by:\n${new globalThis.Error().stack}`);
|
||||
this.destroyed = true;
|
||||
this.shardQueue.clear();
|
||||
for (const shard of this.shards.values()) shard.destroy({ closeCode: 1_000, reset: true, emit: false, log: false });
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
// Heavily inspired by node's `internal/errors` module
|
||||
|
||||
const ErrorCodes = require('./ErrorCodes');
|
||||
const Messages = require('./Messages');
|
||||
const kCode = Symbol('code');
|
||||
const messages = new Map();
|
||||
|
||||
/**
|
||||
* Extend an error of some sort into a DiscordjsError.
|
||||
@@ -13,51 +13,40 @@ const messages = new Map();
|
||||
*/
|
||||
function makeDiscordjsError(Base) {
|
||||
return class DiscordjsError extends Base {
|
||||
constructor(key, ...args) {
|
||||
super(message(key, args));
|
||||
this[kCode] = key;
|
||||
constructor(code, ...args) {
|
||||
super(message(code, args));
|
||||
this[kCode] = code;
|
||||
if (Error.captureStackTrace) Error.captureStackTrace(this, DiscordjsError);
|
||||
}
|
||||
|
||||
get name() {
|
||||
return `${super.name} [${this[kCode]}]`;
|
||||
return `${super.name} [${this.code}]`;
|
||||
}
|
||||
|
||||
get code() {
|
||||
return this[kCode];
|
||||
return ErrorCodes[this[kCode]];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the message for an error.
|
||||
* @param {string} key Error key
|
||||
* @param {string} code The error code
|
||||
* @param {Array<*>} args Arguments to pass for util format or as function args
|
||||
* @returns {string} Formatted string
|
||||
* @ignore
|
||||
*/
|
||||
function message(key, args) {
|
||||
if (typeof key !== 'string') throw new Error('Error message key must be a string');
|
||||
const msg = messages.get(key);
|
||||
if (!msg) throw new Error(`An invalid error message key was used: ${key}.`);
|
||||
function message(code, args) {
|
||||
if (typeof code !== 'number') throw new Error('Error code must be a valid DiscordjsErrorCodes');
|
||||
const msg = Messages[code];
|
||||
if (!msg) throw new Error(`An invalid error code was used: ${code}.`);
|
||||
if (typeof msg === 'function') return msg(...args);
|
||||
if (!args?.length) return msg;
|
||||
args.unshift(msg);
|
||||
return String(...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an error code and message.
|
||||
* @param {string} sym Unique name for the error
|
||||
* @param {*} val Value of the error
|
||||
* @ignore
|
||||
*/
|
||||
function register(sym, val) {
|
||||
messages.set(sym, typeof val === 'function' ? val : String(val));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
register,
|
||||
Error: makeDiscordjsError(Error),
|
||||
TypeError: makeDiscordjsError(TypeError),
|
||||
RangeError: makeDiscordjsError(RangeError),
|
||||
|
||||
298
packages/discord.js/src/errors/ErrorCodes.js
Normal file
298
packages/discord.js/src/errors/ErrorCodes.js
Normal file
@@ -0,0 +1,298 @@
|
||||
'use strict';
|
||||
|
||||
const { createEnum } = require('../util/Enums');
|
||||
|
||||
/**
|
||||
* @typedef {Object} DiscordjsErrorCodes
|
||||
|
||||
* @property {number} ClientInvalidOption
|
||||
* @property {number} ClientInvalidProvidedShards
|
||||
* @property {number} ClientMissingIntents
|
||||
* @property {number} ClientNotReady
|
||||
|
||||
* @property {number} TokenInvalid
|
||||
* @property {number} TokenMissing
|
||||
* @property {number} ApplicationCommandPermissionsTokenMissing
|
||||
|
||||
* @property {number} WSCloseRequested
|
||||
* @property {number} WSConnectionExists
|
||||
* @property {number} WSNotOpen
|
||||
* @property {number} ManagerDestroyed
|
||||
|
||||
* @property {number} BitFieldInvalid
|
||||
|
||||
* @property {number} ShardingInvalid
|
||||
* @property {number} ShardingRequired
|
||||
* @property {number} InvalidIntents
|
||||
* @property {number} DisallowedIntents
|
||||
* @property {number} ShardingNoShards
|
||||
* @property {number} ShardingInProcess
|
||||
* @property {number} ShardingInvalidEvalBroadcast
|
||||
* @property {number} ShardingShardNotFound
|
||||
* @property {number} ShardingAlreadySpawned
|
||||
* @property {number} ShardingProcessExists
|
||||
* @property {number} ShardingWorkerExists
|
||||
* @property {number} ShardingReadyTimeout
|
||||
* @property {number} ShardingReadyDisconnected
|
||||
* @property {number} ShardingReadyDied
|
||||
* @property {number} ShardingNoChildExists
|
||||
* @property {number} ShardingShardMiscalculation
|
||||
|
||||
* @property {number} ColorRange
|
||||
* @property {number} ColorConvert
|
||||
|
||||
* @property {number} InviteOptionsMissingChannel
|
||||
|
||||
* @property {number} ButtonLabel
|
||||
* @property {number} ButtonURL
|
||||
* @property {number} ButtonCustomId
|
||||
|
||||
* @property {number} SelectMenuCustomId
|
||||
* @property {number} SelectMenuPlaceholder
|
||||
* @property {number} SelectOptionLabel
|
||||
* @property {number} SelectOptionValue
|
||||
* @property {number} SelectOptionDescription
|
||||
|
||||
* @property {number} InteractionCollectorError
|
||||
|
||||
* @property {number} FileNotFound
|
||||
|
||||
* @property {number} UserBannerNotFetched
|
||||
* @property {number} UserNoDMChannel
|
||||
|
||||
* @property {number} VoiceNotStageChannel
|
||||
|
||||
* @property {number} VoiceStateNotOwn
|
||||
* @property {number} VoiceStateInvalidType
|
||||
|
||||
* @property {number} ReqResourceType
|
||||
|
||||
* @property {number} ImageFormat
|
||||
* @property {number} ImageSize
|
||||
|
||||
* @property {number} MessageBulkDeleteType
|
||||
* @property {number} MessageNonceType
|
||||
* @property {number} MessageContentType
|
||||
|
||||
* @property {number} SplitMaxLen
|
||||
|
||||
* @property {number} BanResolveId
|
||||
* @property {number} FetchBanResolveId
|
||||
|
||||
* @property {number} PruneDaysType
|
||||
|
||||
* @property {number} GuildChannelResolve
|
||||
* @property {number} GuildVoiceChannelResolve
|
||||
* @property {number} GuildChannelOrphan
|
||||
* @property {number} GuildChannelUnowned
|
||||
* @property {number} GuildOwned
|
||||
* @property {number} GuildMembersTimeout
|
||||
* @property {number} GuildUncachedMe
|
||||
* @property {number} ChannelNotCached
|
||||
* @property {number} StageChannelResolve
|
||||
* @property {number} GuildScheduledEventResolve
|
||||
* @property {number} FetchOwnerId
|
||||
|
||||
* @property {number} InvalidType
|
||||
* @property {number} InvalidElement
|
||||
|
||||
* @property {number} MessageThreadParent
|
||||
* @property {number} MessageExistingThread
|
||||
* @property {number} ThreadInvitableType
|
||||
|
||||
* @property {number} WebhookMessage
|
||||
* @property {number} WebhookTokenUnavailable
|
||||
* @property {number} WebhookURLInvalid
|
||||
* @property {number} WebhookApplication
|
||||
* @property {number} MessageReferenceMissing
|
||||
|
||||
* @property {number} EmojiType
|
||||
* @property {number} EmojiManaged
|
||||
* @property {number} MissingManageEmojisAndStickersPermission
|
||||
* @property {number} NotGuildSticker
|
||||
|
||||
* @property {number} ReactionResolveUser
|
||||
|
||||
* @property {number} VanityURL
|
||||
|
||||
* @property {number} InviteResolveCode
|
||||
|
||||
* @property {number} InviteNotFound
|
||||
|
||||
* @property {number} DeleteGroupDMChannel
|
||||
* @property {number} FetchGroupDMChannel
|
||||
|
||||
* @property {number} MemberFetchNonceLength
|
||||
|
||||
* @property {number} GlobalCommandPermissions
|
||||
* @property {number} GuildUncachedEntityResolve
|
||||
|
||||
* @property {number} InteractionAlreadyReplied
|
||||
* @property {number} InteractionNotReplied
|
||||
* @property {number} InteractionEphemeralReplied
|
||||
|
||||
* @property {number} CommandInteractionOptionNotFound
|
||||
* @property {number} CommandInteractionOptionType
|
||||
* @property {number} CommandInteractionOptionEmpty
|
||||
* @property {number} CommandInteractionOptionNoSubcommand
|
||||
* @property {number} CommandInteractionOptionNoSubcommandGroup
|
||||
* @property {number} AutocompleteInteractionOptionNoFocusedOption
|
||||
|
||||
* @property {number} ModalSubmitInteractionFieldNotFound
|
||||
* @property {number} ModalSubmitInteractionFieldType
|
||||
|
||||
* @property {number} InvalidMissingScopes
|
||||
|
||||
* @property {number} NotImplemented
|
||||
|
||||
* @property {number} SweepFilterReturn
|
||||
*/
|
||||
|
||||
// JSDoc for intellisense purposes
|
||||
/**
|
||||
* @type {DiscordjsErrorCodes}
|
||||
* @ignore
|
||||
*/
|
||||
module.exports = createEnum([
|
||||
'ClientInvalidOption',
|
||||
'ClientInvalidProvidedShards',
|
||||
'ClientMissingIntents',
|
||||
'ClientNotReady',
|
||||
|
||||
'TokenInvalid',
|
||||
'TokenMissing',
|
||||
'ApplicationCommandPermissionsTokenMissing',
|
||||
|
||||
'WSCloseRequested',
|
||||
'WSConnectionExists',
|
||||
'WSNotOpen',
|
||||
'ManagerDestroyed',
|
||||
|
||||
'BitFieldInvalid',
|
||||
|
||||
'ShardingInvalid',
|
||||
'ShardingRequired',
|
||||
'InvalidIntents',
|
||||
'DisallowedIntents',
|
||||
'ShardingNoShards',
|
||||
'ShardingInProcess',
|
||||
'ShardingInvalidEvalBroadcast',
|
||||
'ShardingShardNotFound',
|
||||
'ShardingAlreadySpawned',
|
||||
'ShardingProcessExists',
|
||||
'ShardingWorkerExists',
|
||||
'ShardingReadyTimeout',
|
||||
'ShardingReadyDisconnected',
|
||||
'ShardingReadyDied',
|
||||
'ShardingNoChildExists',
|
||||
'ShardingShardMiscalculation',
|
||||
|
||||
'ColorRange',
|
||||
'ColorConvert',
|
||||
|
||||
'InviteOptionsMissingChannel',
|
||||
|
||||
'ButtonLabel',
|
||||
'ButtonURL',
|
||||
'ButtonCustomId',
|
||||
|
||||
'SelectMenuCustomId',
|
||||
'SelectMenuPlaceholder',
|
||||
'SelectOptionLabel',
|
||||
'SelectOptionValue',
|
||||
'SelectOptionDescription',
|
||||
|
||||
'InteractionCollectorError',
|
||||
|
||||
'FileNotFound',
|
||||
|
||||
'UserBannerNotFetched',
|
||||
'UserNoDMChannel',
|
||||
|
||||
'VoiceNotStageChannel',
|
||||
|
||||
'VoiceStateNotOwn',
|
||||
'VoiceStateInvalidType',
|
||||
|
||||
'ReqResourceType',
|
||||
|
||||
'ImageFormat',
|
||||
'ImageSize',
|
||||
|
||||
'MessageBulkDeleteType',
|
||||
'MessageNonceType',
|
||||
'MessageContentType',
|
||||
|
||||
'SplitMaxLen',
|
||||
|
||||
'BanResolveId',
|
||||
'FetchBanResolveId',
|
||||
|
||||
'PruneDaysType',
|
||||
|
||||
'GuildChannelResolve',
|
||||
'GuildVoiceChannelResolve',
|
||||
'GuildChannelOrphan',
|
||||
'GuildChannelUnowned',
|
||||
'GuildOwned',
|
||||
'GuildMembersTimeout',
|
||||
'GuildUncachedMe',
|
||||
'ChannelNotCached',
|
||||
'StageChannelResolve',
|
||||
'GuildScheduledEventResolve',
|
||||
'FetchOwnerId',
|
||||
|
||||
'InvalidType',
|
||||
'InvalidElement',
|
||||
|
||||
'MessageThreadParent',
|
||||
'MessageExistingThread',
|
||||
'ThreadInvitableType',
|
||||
|
||||
'WebhookMessage',
|
||||
'WebhookTokenUnavailable',
|
||||
'WebhookURLInvalid',
|
||||
'WebhookApplication',
|
||||
'MessageReferenceMissing',
|
||||
|
||||
'EmojiType',
|
||||
'EmojiManaged',
|
||||
'MissingManageEmojisAndStickersPermission',
|
||||
'NotGuildSticker',
|
||||
|
||||
'ReactionResolveUser',
|
||||
|
||||
'VanityURL',
|
||||
|
||||
'InviteResolveCode',
|
||||
|
||||
'InviteNotFound',
|
||||
|
||||
'DeleteGroupDMChannel',
|
||||
'FetchGroupDMChannel',
|
||||
|
||||
'MemberFetchNonceLength',
|
||||
|
||||
'GlobalCommandPermissions',
|
||||
'GuildUncachedEntityResolve',
|
||||
|
||||
'InteractionAlreadyReplied',
|
||||
'InteractionNotReplied',
|
||||
'InteractionEphemeralReplied',
|
||||
|
||||
'CommandInteractionOptionNotFound',
|
||||
'CommandInteractionOptionType',
|
||||
'CommandInteractionOptionEmpty',
|
||||
'CommandInteractionOptionNoSubcommand',
|
||||
'CommandInteractionOptionNoSubcommandGroup',
|
||||
'AutocompleteInteractionOptionNoFocusedOption',
|
||||
|
||||
'ModalSubmitInteractionFieldNotFound',
|
||||
'ModalSubmitInteractionFieldType',
|
||||
|
||||
'InvalidMissingScopes',
|
||||
|
||||
'NotImplemented',
|
||||
|
||||
'SweepFilterReturn',
|
||||
]);
|
||||
@@ -1,164 +1,169 @@
|
||||
'use strict';
|
||||
|
||||
const { register } = require('./DJSError');
|
||||
const DjsErrorCodes = require('./ErrorCodes');
|
||||
|
||||
const Messages = {
|
||||
CLIENT_INVALID_OPTION: (prop, must) => `The ${prop} option must be ${must}`,
|
||||
CLIENT_INVALID_PROVIDED_SHARDS: 'None of the provided shards were valid.',
|
||||
CLIENT_MISSING_INTENTS: 'Valid intents must be provided for the Client.',
|
||||
CLIENT_NOT_READY: action => `The client needs to be logged in to ${action}.`,
|
||||
[DjsErrorCodes.ClientInvalidOption]: (prop, must) => `The ${prop} option must be ${must}`,
|
||||
[DjsErrorCodes.ClientInvalidProvidedShards]: 'None of the provided shards were valid.',
|
||||
[DjsErrorCodes.ClientMissingIntents]: 'Valid intents must be provided for the Client.',
|
||||
[DjsErrorCodes.ClientNotReady]: action => `The client needs to be logged in to ${action}.`,
|
||||
|
||||
TOKEN_INVALID: 'An invalid token was provided.',
|
||||
TOKEN_MISSING: 'Request to use token, but token was unavailable to the client.',
|
||||
APPLICATION_COMMAND_PERMISSIONS_TOKEN_MISSING:
|
||||
[DjsErrorCodes.TokenInvalid]: 'An invalid token was provided.',
|
||||
[DjsErrorCodes.TokenMissing]: 'Request to use token, but token was unavailable to the client.',
|
||||
[DjsErrorCodes.ApplicationCommandPermissionsTokenMissing]:
|
||||
'Editing application command permissions requires an OAuth2 bearer token, but none was provided.',
|
||||
|
||||
WS_CLOSE_REQUESTED: 'WebSocket closed due to user request.',
|
||||
WS_CONNECTION_EXISTS: 'There is already an existing WebSocket connection.',
|
||||
WS_NOT_OPEN: (data = 'data') => `WebSocket not open to send ${data}`,
|
||||
MANAGER_DESTROYED: 'Manager was destroyed.',
|
||||
[DjsErrorCodes.WSCloseRequested]: 'WebSocket closed due to user request.',
|
||||
[DjsErrorCodes.WSConnectionExists]: 'There is already an existing WebSocket connection.',
|
||||
[DjsErrorCodes.WSNotOpen]: (data = 'data') => `WebSocket not open to send ${data}`,
|
||||
[DjsErrorCodes.ManagerDestroyed]: 'Manager was destroyed.',
|
||||
|
||||
BITFIELD_INVALID: bit => `Invalid bitfield flag or number: ${bit}.`,
|
||||
[DjsErrorCodes.BitFieldInvalid]: bit => `Invalid bitfield flag or number: ${bit}.`,
|
||||
|
||||
SHARDING_INVALID: 'Invalid shard settings were provided.',
|
||||
SHARDING_REQUIRED: 'This session would have handled too many guilds - Sharding is required.',
|
||||
INVALID_INTENTS: 'Invalid intent provided for WebSocket intents.',
|
||||
DISALLOWED_INTENTS: 'Privileged intent provided is not enabled or whitelisted.',
|
||||
SHARDING_NO_SHARDS: 'No shards have been spawned.',
|
||||
SHARDING_IN_PROCESS: 'Shards are still being spawned.',
|
||||
SHARDING_INVALID_EVAL_BROADCAST: 'Script to evaluate must be a function',
|
||||
SHARDING_SHARD_NOT_FOUND: id => `Shard ${id} could not be found.`,
|
||||
SHARDING_ALREADY_SPAWNED: count => `Already spawned ${count} shards.`,
|
||||
SHARDING_PROCESS_EXISTS: id => `Shard ${id} already has an active process.`,
|
||||
SHARDING_WORKER_EXISTS: id => `Shard ${id} already has an active worker.`,
|
||||
SHARDING_READY_TIMEOUT: id => `Shard ${id}'s Client took too long to become ready.`,
|
||||
SHARDING_READY_DISCONNECTED: id => `Shard ${id}'s Client disconnected before becoming ready.`,
|
||||
SHARDING_READY_DIED: id => `Shard ${id}'s process exited before its Client became ready.`,
|
||||
SHARDING_NO_CHILD_EXISTS: id => `Shard ${id} has no active process or worker.`,
|
||||
SHARDING_SHARD_MISCALCULATION: (shard, guild, count) =>
|
||||
[DjsErrorCodes.ShardingInvalid]: 'Invalid shard settings were provided.',
|
||||
[DjsErrorCodes.ShardingRequired]: 'This session would have handled too many guilds - Sharding is required.',
|
||||
[DjsErrorCodes.InvalidIntents]: 'Invalid intent provided for WebSocket intents.',
|
||||
[DjsErrorCodes.DisallowedIntents]: 'Privileged intent provided is not enabled or whitelisted.',
|
||||
[DjsErrorCodes.ShardingNoShards]: 'No shards have been spawned.',
|
||||
[DjsErrorCodes.ShardingInProcess]: 'Shards are still being spawned.',
|
||||
[DjsErrorCodes.ShardingInvalidEvalBroadcast]: 'Script to evaluate must be a function',
|
||||
[DjsErrorCodes.ShardingShardNotFound]: id => `Shard ${id} could not be found.`,
|
||||
[DjsErrorCodes.ShardingAlreadySpawned]: count => `Already spawned ${count} shards.`,
|
||||
[DjsErrorCodes.ShardingProcessExists]: id => `Shard ${id} already has an active process.`,
|
||||
[DjsErrorCodes.ShardingWorkerExists]: id => `Shard ${id} already has an active worker.`,
|
||||
[DjsErrorCodes.ShardingReadyTimeout]: id => `Shard ${id}'s Client took too long to become ready.`,
|
||||
[DjsErrorCodes.ShardingReadyDisconnected]: id => `Shard ${id}'s Client disconnected before becoming ready.`,
|
||||
[DjsErrorCodes.ShardingReadyDied]: id => `Shard ${id}'s process exited before its Client became ready.`,
|
||||
[DjsErrorCodes.ShardingNoChildExists]: id => `Shard ${id} has no active process or worker.`,
|
||||
[DjsErrorCodes.ShardingShardMiscalculation]: (shard, guild, count) =>
|
||||
`Calculated invalid shard ${shard} for guild ${guild} with ${count} shards.`,
|
||||
|
||||
COLOR_RANGE: 'Color must be within the range 0 - 16777215 (0xFFFFFF).',
|
||||
COLOR_CONVERT: 'Unable to convert color to a number.',
|
||||
[DjsErrorCodes.ColorRange]: 'Color must be within the range 0 - 16777215 (0xFFFFFF).',
|
||||
[DjsErrorCodes.ColorConvert]: 'Unable to convert color to a number.',
|
||||
|
||||
INVITE_OPTIONS_MISSING_CHANNEL: 'A valid guild channel must be provided when GuildScheduledEvent is EXTERNAL.',
|
||||
[DjsErrorCodes.InviteOptionsMissingChannel]:
|
||||
'A valid guild channel must be provided when GuildScheduledEvent is EXTERNAL.',
|
||||
|
||||
BUTTON_LABEL: 'MessageButton label must be a string',
|
||||
BUTTON_URL: 'MessageButton URL must be a string',
|
||||
BUTTON_CUSTOM_ID: 'MessageButton customId must be a string',
|
||||
[DjsErrorCodes.ButtonLabel]: 'MessageButton label must be a string',
|
||||
[DjsErrorCodes.ButtonURL]: 'MessageButton URL must be a string',
|
||||
[DjsErrorCodes.ButtonCustomId]: 'MessageButton customId must be a string',
|
||||
|
||||
SELECT_MENU_CUSTOM_ID: 'MessageSelectMenu customId must be a string',
|
||||
SELECT_MENU_PLACEHOLDER: 'MessageSelectMenu placeholder must be a string',
|
||||
SELECT_OPTION_LABEL: 'MessageSelectOption label must be a string',
|
||||
SELECT_OPTION_VALUE: 'MessageSelectOption value must be a string',
|
||||
SELECT_OPTION_DESCRIPTION: 'MessageSelectOption description must be a string',
|
||||
[DjsErrorCodes.SelectMenuCustomId]: 'MessageSelectMenu customId must be a string',
|
||||
[DjsErrorCodes.SelectMenuPlaceholder]: 'MessageSelectMenu placeholder must be a string',
|
||||
[DjsErrorCodes.SelectOptionLabel]: 'MessageSelectOption label must be a string',
|
||||
[DjsErrorCodes.SelectOptionValue]: 'MessageSelectOption value must be a string',
|
||||
[DjsErrorCodes.SelectOptionDescription]: 'MessageSelectOption description must be a string',
|
||||
|
||||
INTERACTION_COLLECTOR_ERROR: reason => `Collector received no interactions before ending with reason: ${reason}`,
|
||||
[DjsErrorCodes.InteractionCollectorError]: reason =>
|
||||
`Collector received no interactions before ending with reason: ${reason}`,
|
||||
|
||||
FILE_NOT_FOUND: file => `File could not be found: ${file}`,
|
||||
[DjsErrorCodes.FileNotFound]: file => `File could not be found: ${file}`,
|
||||
|
||||
USER_BANNER_NOT_FETCHED: "You must fetch this user's banner before trying to generate its URL!",
|
||||
USER_NO_DM_CHANNEL: 'No DM Channel exists!',
|
||||
[DjsErrorCodes.UserBannerNotFetched]: "You must fetch this user's banner before trying to generate its URL!",
|
||||
[DjsErrorCodes.UserNoDMChannel]: 'No DM Channel exists!',
|
||||
|
||||
VOICE_NOT_STAGE_CHANNEL: 'You are only allowed to do this in stage channels.',
|
||||
[DjsErrorCodes.VoiceNotStageChannel]: 'You are only allowed to do this in stage channels.',
|
||||
|
||||
VOICE_STATE_NOT_OWN:
|
||||
[DjsErrorCodes.VoiceStateNotOwn]:
|
||||
'You cannot self-deafen/mute/request to speak on VoiceStates that do not belong to the ClientUser.',
|
||||
VOICE_STATE_INVALID_TYPE: name => `${name} must be a boolean.`,
|
||||
[DjsErrorCodes.VoiceStateInvalidType]: name => `${name} must be a boolean.`,
|
||||
|
||||
REQ_RESOURCE_TYPE: 'The resource must be a string, Buffer or a valid file stream.',
|
||||
[DjsErrorCodes.ReqResourceType]: 'The resource must be a string, Buffer or a valid file stream.',
|
||||
|
||||
IMAGE_FORMAT: format => `Invalid image format: ${format}`,
|
||||
IMAGE_SIZE: size => `Invalid image size: ${size}`,
|
||||
[DjsErrorCodes.ImageFormat]: format => `Invalid image format: ${format}`,
|
||||
[DjsErrorCodes.ImageSize]: size => `Invalid image size: ${size}`,
|
||||
|
||||
MESSAGE_BULK_DELETE_TYPE: 'The messages must be an Array, Collection, or number.',
|
||||
MESSAGE_NONCE_TYPE: 'Message nonce must be an integer or a string.',
|
||||
MESSAGE_CONTENT_TYPE: 'Message content must be a string.',
|
||||
[DjsErrorCodes.MessageBulkDeleteType]: 'The messages must be an Array, Collection, or number.',
|
||||
[DjsErrorCodes.MessageNonceType]: 'Message nonce must be an integer or a string.',
|
||||
[DjsErrorCodes.MessageContentType]: 'Message content must be a string.',
|
||||
|
||||
SPLIT_MAX_LEN: 'Chunk exceeds the max length and contains no split characters.',
|
||||
[DjsErrorCodes.SplitMaxLen]: 'Chunk exceeds the max length and contains no split characters.',
|
||||
|
||||
BAN_RESOLVE_ID: (ban = false) => `Couldn't resolve the user id to ${ban ? 'ban' : 'unban'}.`,
|
||||
FETCH_BAN_RESOLVE_ID: "Couldn't resolve the user id to fetch the ban.",
|
||||
[DjsErrorCodes.BanResolveId]: (ban = false) => `Couldn't resolve the user id to ${ban ? 'ban' : 'unban'}.`,
|
||||
[DjsErrorCodes.FetchBanResolveId]: "Couldn't resolve the user id to fetch the ban.",
|
||||
|
||||
PRUNE_DAYS_TYPE: 'Days must be a number',
|
||||
[DjsErrorCodes.PruneDaysType]: 'Days must be a number',
|
||||
|
||||
GUILD_CHANNEL_RESOLVE: 'Could not resolve channel to a guild channel.',
|
||||
GUILD_VOICE_CHANNEL_RESOLVE: 'Could not resolve channel to a guild voice channel.',
|
||||
GUILD_CHANNEL_ORPHAN: 'Could not find a parent to this guild channel.',
|
||||
GUILD_CHANNEL_UNOWNED: "The fetched channel does not belong to this manager's guild.",
|
||||
GUILD_OWNED: 'Guild is owned by the client.',
|
||||
GUILD_MEMBERS_TIMEOUT: "Members didn't arrive in time.",
|
||||
GUILD_UNCACHED_ME: 'The client user as a member of this guild is uncached.',
|
||||
CHANNEL_NOT_CACHED: 'Could not find the channel where this message came from in the cache!',
|
||||
STAGE_CHANNEL_RESOLVE: 'Could not resolve channel to a stage channel.',
|
||||
GUILD_SCHEDULED_EVENT_RESOLVE: 'Could not resolve the guild scheduled event.',
|
||||
FETCH_OWNER_ID: "Couldn't resolve the guild ownerId to fetch the member.",
|
||||
[DjsErrorCodes.GuildChannelResolve]: 'Could not resolve channel to a guild channel.',
|
||||
[DjsErrorCodes.GuildVoiceChannelResolve]: 'Could not resolve channel to a guild voice channel.',
|
||||
[DjsErrorCodes.GuildChannelOrphan]: 'Could not find a parent to this guild channel.',
|
||||
[DjsErrorCodes.GuildChannelUnowned]: "The fetched channel does not belong to this manager's guild.",
|
||||
[DjsErrorCodes.GuildOwned]: 'Guild is owned by the client.',
|
||||
[DjsErrorCodes.GuildMembersTimeout]: "Members didn't arrive in time.",
|
||||
[DjsErrorCodes.GuildUncachedMe]: 'The client user as a member of this guild is uncached.',
|
||||
[DjsErrorCodes.ChannelNotCached]: 'Could not find the channel where this message came from in the cache!',
|
||||
[DjsErrorCodes.StageChannelResolve]: 'Could not resolve channel to a stage channel.',
|
||||
[DjsErrorCodes.GuildScheduledEventResolve]: 'Could not resolve the guild scheduled event.',
|
||||
[DjsErrorCodes.FetchOwnerId]: "Couldn't resolve the guild ownerId to fetch the member.",
|
||||
|
||||
INVALID_TYPE: (name, expected, an = false) => `Supplied ${name} is not a${an ? 'n' : ''} ${expected}.`,
|
||||
INVALID_ELEMENT: (type, name, elem) => `Supplied ${type} ${name} includes an invalid element: ${elem}`,
|
||||
[DjsErrorCodes.InvalidType]: (name, expected, an = false) => `Supplied ${name} is not a${an ? 'n' : ''} ${expected}.`,
|
||||
[DjsErrorCodes.InvalidElement]: (type, name, elem) => `Supplied ${type} ${name} includes an invalid element: ${elem}`,
|
||||
|
||||
MESSAGE_THREAD_PARENT: 'The message was not sent in a guild text or news channel',
|
||||
MESSAGE_EXISTING_THREAD: 'The message already has a thread',
|
||||
THREAD_INVITABLE_TYPE: type => `Invitable cannot be edited on ${type}`,
|
||||
[DjsErrorCodes.MessageThreadParent]: 'The message was not sent in a guild text or news channel',
|
||||
[DjsErrorCodes.MessageExistingThread]: 'The message already has a thread',
|
||||
[DjsErrorCodes.ThreadInvitableType]: type => `Invitable cannot be edited on ${type}`,
|
||||
|
||||
WEBHOOK_MESSAGE: 'The message was not sent by a webhook.',
|
||||
WEBHOOK_TOKEN_UNAVAILABLE: 'This action requires a webhook token, but none is available.',
|
||||
WEBHOOK_URL_INVALID: 'The provided webhook URL is not valid.',
|
||||
WEBHOOK_APPLICATION: 'This message webhook belongs to an application and cannot be fetched.',
|
||||
MESSAGE_REFERENCE_MISSING: 'The message does not reference another message',
|
||||
[DjsErrorCodes.WebhookMessage]: 'The message was not sent by a webhook.',
|
||||
[DjsErrorCodes.WebhookTokenUnavailable]: 'This action requires a webhook token, but none is available.',
|
||||
[DjsErrorCodes.WebhookURLInvalid]: 'The provided webhook URL is not valid.',
|
||||
[DjsErrorCodes.WebhookApplication]: 'This message webhook belongs to an application and cannot be fetched.',
|
||||
[DjsErrorCodes.MessageReferenceMissing]: 'The message does not reference another message',
|
||||
|
||||
EMOJI_TYPE: 'Emoji must be a string or GuildEmoji/ReactionEmoji',
|
||||
EMOJI_MANAGED: 'Emoji is managed and has no Author.',
|
||||
MISSING_MANAGE_EMOJIS_AND_STICKERS_PERMISSION: guild =>
|
||||
[DjsErrorCodes.EmojiType]: 'Emoji must be a string or GuildEmoji/ReactionEmoji',
|
||||
[DjsErrorCodes.EmojiManaged]: 'Emoji is managed and has no Author.',
|
||||
[DjsErrorCodes.MissingManageEmojisAndStickersPermission]: guild =>
|
||||
`Client must have Manage Emojis and Stickers permission in guild ${guild} to see emoji authors.`,
|
||||
NOT_GUILD_STICKER: 'Sticker is a standard (non-guild) sticker and has no author.',
|
||||
[DjsErrorCodes.NotGuildSticker]: 'Sticker is a standard (non-guild) sticker and has no author.',
|
||||
|
||||
REACTION_RESOLVE_USER: "Couldn't resolve the user id to remove from the reaction.",
|
||||
[DjsErrorCodes.ReactionResolveUser]: "Couldn't resolve the user id to remove from the reaction.",
|
||||
|
||||
VANITY_URL: 'This guild does not have the VANITY_URL feature enabled.',
|
||||
[DjsErrorCodes.VanityURL]: 'This guild does not have the vanity URL feature enabled.',
|
||||
|
||||
INVITE_RESOLVE_CODE: 'Could not resolve the code to fetch the invite.',
|
||||
[DjsErrorCodes.InviteResolveCode]: 'Could not resolve the code to fetch the invite.',
|
||||
|
||||
INVITE_NOT_FOUND: 'Could not find the requested invite.',
|
||||
[DjsErrorCodes.InviteNotFound]: 'Could not find the requested invite.',
|
||||
|
||||
DELETE_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot delete them",
|
||||
FETCH_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot fetch them",
|
||||
[DjsErrorCodes.DeleteGroupDMChannel]: "Bots don't have access to Group DM Channels and cannot delete them",
|
||||
[DjsErrorCodes.FetchGroupDMChannel]: "Bots don't have access to Group DM Channels and cannot fetch them",
|
||||
|
||||
MEMBER_FETCH_NONCE_LENGTH: 'Nonce length must not exceed 32 characters.',
|
||||
[DjsErrorCodes.MemberFetchNonceLength]: 'Nonce length must not exceed 32 characters.',
|
||||
|
||||
GLOBAL_COMMAND_PERMISSIONS:
|
||||
[DjsErrorCodes.GlobalCommandPermissions]:
|
||||
'Permissions for global commands may only be fetched or modified by providing a GuildResolvable ' +
|
||||
"or from a guild's application command manager.",
|
||||
GUILD_UNCACHED_ENTITY_RESOLVE: type => `Cannot resolve ${type} from an arbitrary guild, provide an id instead`,
|
||||
[DjsErrorCodes.GuildUncachedEntityResolve]: type =>
|
||||
`Cannot resolve ${type} from an arbitrary guild, provide an id instead`,
|
||||
|
||||
INTERACTION_ALREADY_REPLIED: 'The reply to this interaction has already been sent or deferred.',
|
||||
INTERACTION_NOT_REPLIED: 'The reply to this interaction has not been sent or deferred.',
|
||||
INTERACTION_EPHEMERAL_REPLIED: 'Ephemeral responses cannot be deleted.',
|
||||
[DjsErrorCodes.InteractionAlreadyReplied]: 'The reply to this interaction has already been sent or deferred.',
|
||||
[DjsErrorCodes.InteractionNotReplied]: 'The reply to this interaction has not been sent or deferred.',
|
||||
[DjsErrorCodes.InteractionEphemeralReplied]: 'Ephemeral responses cannot be deleted.',
|
||||
|
||||
COMMAND_INTERACTION_OPTION_NOT_FOUND: name => `Required option "${name}" not found.`,
|
||||
COMMAND_INTERACTION_OPTION_TYPE: (name, type, expected) =>
|
||||
[DjsErrorCodes.CommandInteractionOptionNotFound]: name => `Required option "${name}" not found.`,
|
||||
[DjsErrorCodes.CommandInteractionOptionType]: (name, type, expected) =>
|
||||
`Option "${name}" is of type: ${type}; expected ${expected}.`,
|
||||
COMMAND_INTERACTION_OPTION_EMPTY: (name, type) =>
|
||||
[DjsErrorCodes.CommandInteractionOptionEmpty]: (name, type) =>
|
||||
`Required option "${name}" is of type: ${type}; expected a non-empty value.`,
|
||||
COMMAND_INTERACTION_OPTION_NO_SUB_COMMAND: 'No subcommand specified for interaction.',
|
||||
COMMAND_INTERACTION_OPTION_NO_SUB_COMMAND_GROUP: 'No subcommand group specified for interaction.',
|
||||
AUTOCOMPLETE_INTERACTION_OPTION_NO_FOCUSED_OPTION: 'No focused option for autocomplete interaction.',
|
||||
[DjsErrorCodes.CommandInteractionOptionNoSubcommand]: 'No subcommand specified for interaction.',
|
||||
[DjsErrorCodes.CommandInteractionOptionNoSubcommandGroup]: 'No subcommand group specified for interaction.',
|
||||
[DjsErrorCodes.AutocompleteInteractionOptionNoFocusedOption]: 'No focused option for autocomplete interaction.',
|
||||
|
||||
MODAL_SUBMIT_INTERACTION_FIELD_NOT_FOUND: customId => `Required field with custom id "${customId}" not found.`,
|
||||
MODAL_SUBMIT_INTERACTION_FIELD_TYPE: (customId, type, expected) =>
|
||||
[DjsErrorCodes.ModalSubmitInteractionFieldNotFound]: customId =>
|
||||
`Required field with custom id "${customId}" not found.`,
|
||||
[DjsErrorCodes.ModalSubmitInteractionFieldType]: (customId, type, expected) =>
|
||||
`Field with custom id "${customId}" is of type: ${type}; expected ${expected}.`,
|
||||
|
||||
INVITE_MISSING_SCOPES: 'At least one valid scope must be provided for the invite',
|
||||
[DjsErrorCodes.InvalidMissingScopes]: 'At least one valid scope must be provided for the invite',
|
||||
|
||||
NOT_IMPLEMENTED: (what, name) => `Method ${what} not implemented on ${name}.`,
|
||||
[DjsErrorCodes.NotImplemented]: (what, name) => `Method ${what} not implemented on ${name}.`,
|
||||
|
||||
SWEEP_FILTER_RETURN: 'The return value of the sweepFilter function was not false or a Function',
|
||||
[DjsErrorCodes.SweepFilterReturn]: 'The return value of the sweepFilter function was not false or a Function',
|
||||
};
|
||||
|
||||
Messages.AuthenticationFailed = Messages.TOKEN_INVALID;
|
||||
Messages.InvalidShard = Messages.SHARDING_INVALID;
|
||||
Messages.ShardingRequired = Messages.SHARDING_REQUIRED;
|
||||
Messages.InvalidIntents = Messages.INVALID_INTENTS;
|
||||
Messages.DisallowedIntents = Messages.DISALLOWED_INTENTS;
|
||||
// Magic needed by WS
|
||||
Messages.AuthenticationFailed = Messages[DjsErrorCodes.AuthenticationFailed];
|
||||
Messages.InvalidShard = Messages[DjsErrorCodes.ShardingInvalid];
|
||||
Messages.ShardingRequired = Messages[DjsErrorCodes.ShardingRequired];
|
||||
Messages.InvalidIntents = Messages[DjsErrorCodes.InvalidIntents];
|
||||
Messages.DisallowedIntents = Messages[DjsErrorCodes.DisallowedIntents];
|
||||
|
||||
for (const [name, message] of Object.entries(Messages)) register(name, message);
|
||||
module.exports = Messages;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = require('./DJSError');
|
||||
module.exports.ErrorCodes = require('./ErrorCodes');
|
||||
module.exports.Messages = require('./Messages');
|
||||
|
||||
@@ -10,6 +10,13 @@ exports.ShardClientUtil = require('./sharding/ShardClientUtil');
|
||||
exports.ShardingManager = require('./sharding/ShardingManager');
|
||||
exports.WebhookClient = require('./client/WebhookClient');
|
||||
|
||||
// Errors
|
||||
const { Error, TypeError, RangeError } = require('./errors/DJSError');
|
||||
exports.DiscordjsError = Error;
|
||||
exports.DiscordjsTypeError = TypeError;
|
||||
exports.DiscordjsRangeError = RangeError;
|
||||
exports.DiscordjsErrorCodes = require('./errors/ErrorCodes');
|
||||
|
||||
// Utilities
|
||||
exports.ActivityFlagsBitField = require('./util/ActivityFlagsBitField');
|
||||
exports.ApplicationFlagsBitField = require('./util/ApplicationFlagsBitField');
|
||||
|
||||
@@ -4,7 +4,7 @@ const { Collection } = require('@discordjs/collection');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const ApplicationCommandPermissionsManager = require('./ApplicationCommandPermissionsManager');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const ApplicationCommand = require('../structures/ApplicationCommand');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
|
||||
@@ -187,7 +187,7 @@ class ApplicationCommandManager extends CachedManager {
|
||||
*/
|
||||
async edit(command, data, guildId) {
|
||||
const id = this.resolveId(command);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable');
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable');
|
||||
|
||||
const patched = await this.client.rest.patch(this.commandPath({ id, guildId }), {
|
||||
body: this.constructor.transformCommand(data),
|
||||
@@ -209,7 +209,7 @@ class ApplicationCommandManager extends CachedManager {
|
||||
*/
|
||||
async delete(command, guildId) {
|
||||
const id = this.resolveId(command);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable');
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable');
|
||||
|
||||
await this.client.rest.delete(this.commandPath({ id, guildId }));
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { ApplicationCommandPermissionType, RESTJSONErrorCodes, Routes } = require('discord-api-types/v10');
|
||||
const BaseManager = require('./BaseManager');
|
||||
const { Error, TypeError } = require('../errors');
|
||||
const { Error, TypeError, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Manages API methods for permissions of Application Commands.
|
||||
@@ -153,12 +153,12 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
*/
|
||||
async set({ guild, command, permissions, token } = {}) {
|
||||
if (!token) {
|
||||
throw new Error('APPLICATION_COMMAND_PERMISSIONS_TOKEN_MISSING');
|
||||
throw new Error(ErrorCodes.ApplicationCommandPermissionsTokenMissing);
|
||||
}
|
||||
let { guildId, commandId } = this._validateOptions(guild, command);
|
||||
|
||||
if (!Array.isArray(permissions)) {
|
||||
throw new TypeError('INVALID_TYPE', 'permissions', 'Array of ApplicationCommandPermissions', true);
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'permissions', 'Array of ApplicationCommandPermissions', true);
|
||||
}
|
||||
|
||||
if (!commandId) {
|
||||
@@ -190,14 +190,14 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
*/
|
||||
async add({ guild, command, permissions, token } = {}) {
|
||||
if (!token) {
|
||||
throw new Error('APPLICATION_COMMAND_PERMISSIONS_TOKEN_MISSING');
|
||||
throw new Error(ErrorCodes.ApplicationCommandPermissionsTokenMissing);
|
||||
}
|
||||
let { guildId, commandId } = this._validateOptions(guild, command);
|
||||
if (!commandId) {
|
||||
commandId = this.client.user.id;
|
||||
}
|
||||
if (!Array.isArray(permissions)) {
|
||||
throw new TypeError('INVALID_TYPE', 'permissions', 'Array of ApplicationCommandPermissions', true);
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'permissions', 'Array of ApplicationCommandPermissions', true);
|
||||
}
|
||||
|
||||
let existing = [];
|
||||
@@ -262,7 +262,7 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
*/
|
||||
async remove({ guild, command, users, roles, channels, token } = {}) {
|
||||
if (!token) {
|
||||
throw new Error('APPLICATION_COMMAND_PERMISSIONS_TOKEN_MISSING');
|
||||
throw new Error(ErrorCodes.ApplicationCommandPermissionsTokenMissing);
|
||||
}
|
||||
let { guildId, commandId } = this._validateOptions(guild, command);
|
||||
if (!commandId) {
|
||||
@@ -270,14 +270,14 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
}
|
||||
|
||||
if (!users && !roles && !channels) {
|
||||
throw new TypeError('INVALID_TYPE', 'users OR roles OR channels', 'Array or Resolvable', true);
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'users OR roles OR channels', 'Array or Resolvable', true);
|
||||
}
|
||||
|
||||
let resolvedUserIds = [];
|
||||
if (Array.isArray(users)) {
|
||||
for (const user of users) {
|
||||
const userId = this.client.users.resolveId(user);
|
||||
if (!userId) throw new TypeError('INVALID_ELEMENT', 'Array', 'users', user);
|
||||
if (!userId) throw new TypeError(ErrorCodes.InvalidElement, 'Array', 'users', user);
|
||||
resolvedUserIds.push(userId);
|
||||
}
|
||||
}
|
||||
@@ -289,9 +289,9 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
resolvedRoleIds.push(role);
|
||||
continue;
|
||||
}
|
||||
if (!this.guild) throw new Error('GUILD_UNCACHED_ENTITY_RESOLVE', 'roles');
|
||||
if (!this.guild) throw new Error(ErrorCodes.GuildUncachedEntityResolve, 'roles');
|
||||
const roleId = this.guild.roles.resolveId(role);
|
||||
if (!roleId) throw new TypeError('INVALID_ELEMENT', 'Array', 'users', role);
|
||||
if (!roleId) throw new TypeError(ErrorCodes.InvalidElement, 'Array', 'users', role);
|
||||
resolvedRoleIds.push(roleId);
|
||||
}
|
||||
}
|
||||
@@ -303,9 +303,9 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
resolvedChannelIds.push(channel);
|
||||
continue;
|
||||
}
|
||||
if (!this.guild) throw new Error('GUILD_UNCACHED_ENTITY_RESOLVE', 'channels');
|
||||
if (!this.guild) throw new Error(ErrorCodes.GuildUncachedEntityResolve, 'channels');
|
||||
const channelId = this.guild.channels.resolveId(channel);
|
||||
if (!channelId) throw new TypeError('INVALID_ELEMENT', 'Array', 'channels', channel);
|
||||
if (!channelId) throw new TypeError(ErrorCodes.InvalidElement, 'Array', 'channels', channel);
|
||||
resolvedChannelIds.push(channelId);
|
||||
}
|
||||
}
|
||||
@@ -353,11 +353,11 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
*/
|
||||
async has({ guild, command, permissionId, permissionType }) {
|
||||
const { guildId, commandId } = this._validateOptions(guild, command);
|
||||
if (!commandId) throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable');
|
||||
if (!commandId) throw new TypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable');
|
||||
|
||||
if (!permissionId) {
|
||||
throw new TypeError(
|
||||
'INVALID_TYPE',
|
||||
ErrorCodes.InvalidType,
|
||||
'permissionId',
|
||||
'UserResolvable, RoleResolvable, ChannelResolvable, or Permission Constant',
|
||||
);
|
||||
@@ -366,7 +366,7 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
if (typeof permissionId !== 'string') {
|
||||
resolvedId = this.client.users.resolveId(permissionId);
|
||||
if (!resolvedId) {
|
||||
if (!this.guild) throw new Error('GUILD_UNCACHED_ENTITY_RESOLVE', 'roles');
|
||||
if (!this.guild) throw new Error(ErrorCodes.GuildUncachedEntityResolve, 'roles');
|
||||
resolvedId = this.guild.roles.resolveId(permissionId);
|
||||
}
|
||||
if (!resolvedId) {
|
||||
@@ -374,7 +374,7 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
}
|
||||
if (!resolvedId) {
|
||||
throw new TypeError(
|
||||
'INVALID_TYPE',
|
||||
ErrorCodes.InvalidType,
|
||||
'permissionId',
|
||||
'UserResolvable, RoleResolvable, ChannelResolvable, or Permission Constant',
|
||||
);
|
||||
@@ -394,7 +394,7 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
|
||||
_validateOptions(guild, command) {
|
||||
const guildId = this.guildId ?? this.client.guilds.resolveId(guild);
|
||||
if (!guildId) throw new Error('GLOBAL_COMMAND_PERMISSIONS');
|
||||
if (!guildId) throw new Error(ErrorCodes.GlobalCommandPermissions);
|
||||
let commandId = this.commandId;
|
||||
if (command && !commandId) {
|
||||
commandId = this.manager.resolveId?.(command);
|
||||
@@ -403,7 +403,7 @@ class ApplicationCommandPermissionsManager extends BaseManager {
|
||||
}
|
||||
commandId ??= this.client.application?.commands.resolveId(command);
|
||||
if (!commandId) {
|
||||
throw new TypeError('INVALID_TYPE', 'command', 'ApplicationCommandResolvable', true);
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable', true);
|
||||
}
|
||||
}
|
||||
return { guildId, commandId };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const BaseManager = require('./BaseManager');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Manages the API methods of a data model along with a collection of instances.
|
||||
@@ -28,7 +28,7 @@ class DataManager extends BaseManager {
|
||||
* @abstract
|
||||
*/
|
||||
get cache() {
|
||||
throw new Error('NOT_IMPLEMENTED', 'get cache', this.constructor.name);
|
||||
throw new Error(ErrorCodes.NotImplemented, 'get cache', this.constructor.name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@ const { Collection } = require('@discordjs/collection');
|
||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError, Error } = require('../errors');
|
||||
const { TypeError, Error, ErrorCodes } = require('../errors');
|
||||
const GuildBan = require('../structures/GuildBan');
|
||||
const { GuildMember } = require('../structures/GuildMember');
|
||||
|
||||
@@ -101,7 +101,7 @@ class GuildBanManager extends CachedManager {
|
||||
if (resolvedUser) return this._fetchSingle({ user: resolvedUser, cache, force });
|
||||
|
||||
if (!before && !after && !limit && typeof cache === 'undefined') {
|
||||
return Promise.reject(new Error('FETCH_BAN_RESOLVE_ID'));
|
||||
return Promise.reject(new Error(ErrorCodes.FetchBanResolveId));
|
||||
}
|
||||
|
||||
return this._fetchMany(options);
|
||||
@@ -146,9 +146,9 @@ class GuildBanManager extends CachedManager {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async create(user, options = {}) {
|
||||
if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true);
|
||||
if (typeof options !== 'object') throw new TypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
||||
const id = this.client.users.resolveId(user);
|
||||
if (!id) throw new Error('BAN_RESOLVE_ID', true);
|
||||
if (!id) throw new Error(ErrorCodes.BanResolveId, true);
|
||||
await this.client.rest.put(Routes.guildBan(this.guild.id, id), {
|
||||
body: { delete_message_days: options.deleteMessageDays },
|
||||
reason: options.reason,
|
||||
@@ -174,7 +174,7 @@ class GuildBanManager extends CachedManager {
|
||||
*/
|
||||
async remove(user, reason) {
|
||||
const id = this.client.users.resolveId(user);
|
||||
if (!id) throw new Error('BAN_RESOLVE_ID');
|
||||
if (!id) throw new Error(ErrorCodes.BanResolveId);
|
||||
await this.client.rest.delete(Routes.guildBan(this.guild.id, id), { reason });
|
||||
return this.client.users.resolve(user);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ const { Collection } = require('@discordjs/collection');
|
||||
const { ChannelType, Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const ThreadManager = require('./ThreadManager');
|
||||
const { Error, TypeError } = require('../errors');
|
||||
const { Error, TypeError, ErrorCodes } = require('../errors');
|
||||
const GuildChannel = require('../structures/GuildChannel');
|
||||
const PermissionOverwrites = require('../structures/PermissionOverwrites');
|
||||
const ThreadChannel = require('../structures/ThreadChannel');
|
||||
@@ -184,7 +184,7 @@ class GuildChannelManager extends CachedManager {
|
||||
*/
|
||||
async createWebhook({ channel, name, avatar, reason }) {
|
||||
const id = this.resolveId(channel);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'channel', 'GuildChannelResolvable');
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
|
||||
if (typeof avatar === 'string' && !avatar.startsWith('data:')) {
|
||||
avatar = await DataResolver.resolveImage(avatar);
|
||||
}
|
||||
@@ -234,7 +234,7 @@ class GuildChannelManager extends CachedManager {
|
||||
*/
|
||||
async edit(channel, data) {
|
||||
channel = this.resolve(channel);
|
||||
if (!channel) throw new TypeError('INVALID_TYPE', 'channel', 'GuildChannelResolvable');
|
||||
if (!channel) throw new TypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
|
||||
|
||||
const parent = data.parent && this.client.channels.resolveId(data.parent);
|
||||
|
||||
@@ -295,7 +295,7 @@ class GuildChannelManager extends CachedManager {
|
||||
*/
|
||||
async setPosition(channel, position, { relative, reason } = {}) {
|
||||
channel = this.resolve(channel);
|
||||
if (!channel) throw new TypeError('INVALID_TYPE', 'channel', 'GuildChannelResolvable');
|
||||
if (!channel) throw new TypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
|
||||
const updatedChannels = await setPosition(
|
||||
channel,
|
||||
position,
|
||||
@@ -338,7 +338,7 @@ class GuildChannelManager extends CachedManager {
|
||||
if (id) {
|
||||
const data = await this.client.rest.get(Routes.channel(id));
|
||||
// Since this is the guild manager, throw if on a different guild
|
||||
if (this.guild.id !== data.guild_id) throw new Error('GUILD_CHANNEL_UNOWNED');
|
||||
if (this.guild.id !== data.guild_id) throw new Error(ErrorCodes.GuildChannelUnowned);
|
||||
return this.client.channels._add(data, this.guild, { cache });
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ class GuildChannelManager extends CachedManager {
|
||||
*/
|
||||
async fetchWebhooks(channel) {
|
||||
const id = this.resolveId(channel);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'channel', 'GuildChannelResolvable');
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
|
||||
const data = await this.client.rest.get(Routes.channelWebhooks(id));
|
||||
return data.reduce((hooks, hook) => hooks.set(hook.id, new Webhook(this.client, hook)), new Collection());
|
||||
}
|
||||
@@ -434,7 +434,7 @@ class GuildChannelManager extends CachedManager {
|
||||
*/
|
||||
async delete(channel, reason) {
|
||||
const id = this.resolveId(channel);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'channel', 'GuildChannelResolvable');
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
|
||||
await this.client.rest.delete(Routes.channel(id), { reason });
|
||||
this.client.actions.ChannelDelete.handle({ id });
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { Routes, PermissionFlagsBits } = require('discord-api-types/v10');
|
||||
const BaseGuildEmojiManager = require('./BaseGuildEmojiManager');
|
||||
const { Error, TypeError } = require('../errors');
|
||||
const { Error, TypeError, ErrorCodes } = require('../errors');
|
||||
const DataResolver = require('../util/DataResolver');
|
||||
|
||||
/**
|
||||
@@ -51,17 +51,24 @@ class GuildEmojiManager extends BaseGuildEmojiManager {
|
||||
*/
|
||||
async create({ attachment, name, roles, reason }) {
|
||||
attachment = await DataResolver.resolveImage(attachment);
|
||||
if (!attachment) throw new TypeError('REQ_RESOURCE_TYPE');
|
||||
if (!attachment) throw new TypeError(ErrorCodes.ReqResourceType);
|
||||
|
||||
const body = { image: attachment, name };
|
||||
if (roles) {
|
||||
if (!Array.isArray(roles) && !(roles instanceof Collection)) {
|
||||
throw new TypeError('INVALID_TYPE', 'options.roles', 'Array or Collection of Roles or Snowflakes', true);
|
||||
throw new TypeError(
|
||||
ErrorCodes.InvalidType,
|
||||
'options.roles',
|
||||
'Array or Collection of Roles or Snowflakes',
|
||||
true,
|
||||
);
|
||||
}
|
||||
body.roles = [];
|
||||
for (const role of roles.values()) {
|
||||
const resolvedRole = this.guild.roles.resolveId(role);
|
||||
if (!resolvedRole) throw new TypeError('INVALID_ELEMENT', 'Array or Collection', 'options.roles', role);
|
||||
if (!resolvedRole) {
|
||||
throw new TypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'options.roles', role);
|
||||
}
|
||||
body.roles.push(resolvedRole);
|
||||
}
|
||||
}
|
||||
@@ -110,7 +117,7 @@ class GuildEmojiManager extends BaseGuildEmojiManager {
|
||||
*/
|
||||
async delete(emoji, reason) {
|
||||
const id = this.resolveId(emoji);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'emoji', 'EmojiResolvable', true);
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
|
||||
await this.client.rest.delete(Routes.guildEmoji(this.guild.id, id), { reason });
|
||||
}
|
||||
|
||||
@@ -122,7 +129,7 @@ class GuildEmojiManager extends BaseGuildEmojiManager {
|
||||
*/
|
||||
async edit(emoji, data) {
|
||||
const id = this.resolveId(emoji);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'emoji', 'EmojiResolvable', true);
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
|
||||
const roles = data.roles?.map(r => this.guild.roles.resolveId(r));
|
||||
const newData = await this.client.rest.patch(Routes.guildEmoji(this.guild.id, id), {
|
||||
body: {
|
||||
@@ -147,15 +154,15 @@ class GuildEmojiManager extends BaseGuildEmojiManager {
|
||||
*/
|
||||
async fetchAuthor(emoji) {
|
||||
emoji = this.resolve(emoji);
|
||||
if (!emoji) throw new TypeError('INVALID_TYPE', 'emoji', 'EmojiResolvable', true);
|
||||
if (!emoji) throw new TypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
|
||||
if (emoji.managed) {
|
||||
throw new Error('EMOJI_MANAGED');
|
||||
throw new Error(ErrorCodes.EmojiManaged);
|
||||
}
|
||||
|
||||
const { me } = this.guild.members;
|
||||
if (!me) throw new Error('GUILD_UNCACHED_ME');
|
||||
if (!me) throw new Error(ErrorCodes.GuildUncachedMe);
|
||||
if (!me.permissions.has(PermissionFlagsBits.ManageEmojisAndStickers)) {
|
||||
throw new Error('MISSING_MANAGE_EMOJIS_AND_STICKERS_PERMISSION', this.guild);
|
||||
throw new Error(ErrorCodes.MissingManageEmojisAndStickersPermission, this.guild);
|
||||
}
|
||||
|
||||
const data = await this.client.rest.get(Routes.guildEmoji(this.guild.id, emoji.id));
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const DataManager = require('./DataManager');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const { Role } = require('../structures/Role');
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ class GuildEmojiRoleManager extends DataManager {
|
||||
for (const role of roleOrRoles.values()) {
|
||||
const resolvedRole = this.guild.roles.resolveId(role);
|
||||
if (!resolvedRole) {
|
||||
return Promise.reject(new TypeError('INVALID_ELEMENT', 'Array or Collection', 'roles', role));
|
||||
return Promise.reject(new TypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role));
|
||||
}
|
||||
resolvedRoles.push(resolvedRole);
|
||||
}
|
||||
@@ -67,7 +67,7 @@ class GuildEmojiRoleManager extends DataManager {
|
||||
for (const role of roleOrRoles.values()) {
|
||||
const roleId = this.guild.roles.resolveId(role);
|
||||
if (!roleId) {
|
||||
return Promise.reject(new TypeError('INVALID_ELEMENT', 'Array or Collection', 'roles', role));
|
||||
return Promise.reject(new TypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role));
|
||||
}
|
||||
resolvedRoleIds.push(roleId);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const Invite = require('../structures/Invite');
|
||||
const DataResolver = require('../util/DataResolver');
|
||||
|
||||
@@ -123,18 +123,18 @@ class GuildInviteManager extends CachedManager {
|
||||
if (!options) return this._fetchMany();
|
||||
if (typeof options === 'string') {
|
||||
const code = DataResolver.resolveInviteCode(options);
|
||||
if (!code) return Promise.reject(new Error('INVITE_RESOLVE_CODE'));
|
||||
if (!code) return Promise.reject(new Error(ErrorCodes.InviteResolveCode));
|
||||
return this._fetchSingle({ code, cache: true });
|
||||
}
|
||||
if (!options.code) {
|
||||
if (options.channelId) {
|
||||
const id = this.guild.channels.resolveId(options.channelId);
|
||||
if (!id) return Promise.reject(new Error('GUILD_CHANNEL_RESOLVE'));
|
||||
if (!id) return Promise.reject(new Error(ErrorCodes.GuildChannelResolve));
|
||||
return this._fetchChannelMany(id, options.cache);
|
||||
}
|
||||
|
||||
if ('cache' in options) return this._fetchMany(options.cache);
|
||||
return Promise.reject(new Error('INVITE_RESOLVE_CODE'));
|
||||
return Promise.reject(new Error(ErrorCodes.InviteResolveCode));
|
||||
}
|
||||
return this._fetchSingle({
|
||||
...options,
|
||||
@@ -150,7 +150,7 @@ class GuildInviteManager extends CachedManager {
|
||||
|
||||
const invites = await this._fetchMany(cache);
|
||||
const invite = invites.get(code);
|
||||
if (!invite) throw new Error('INVITE_NOT_FOUND');
|
||||
if (!invite) throw new Error(ErrorCodes.InviteNotFound);
|
||||
return invite;
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ class GuildInviteManager extends CachedManager {
|
||||
{ temporary, maxAge, maxUses, unique, targetUser, targetApplication, targetType, reason } = {},
|
||||
) {
|
||||
const id = this.guild.channels.resolveId(channel);
|
||||
if (!id) throw new Error('GUILD_CHANNEL_RESOLVE');
|
||||
if (!id) throw new Error(ErrorCodes.GuildChannelResolve);
|
||||
|
||||
const invite = await this.client.rest.post(Routes.channelInvites(id), {
|
||||
body: {
|
||||
|
||||
@@ -7,7 +7,7 @@ const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { Routes, GatewayOpcodes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { Error, TypeError, RangeError } = require('../errors');
|
||||
const { Error, TypeError, RangeError, ErrorCodes } = require('../errors');
|
||||
const BaseGuildVoiceChannel = require('../structures/BaseGuildVoiceChannel');
|
||||
const { GuildMember } = require('../structures/GuildMember');
|
||||
const { Role } = require('../structures/Role');
|
||||
@@ -93,7 +93,7 @@ class GuildMemberManager extends CachedManager {
|
||||
*/
|
||||
async add(user, options) {
|
||||
const userId = this.client.users.resolveId(user);
|
||||
if (!userId) throw new TypeError('INVALID_TYPE', 'user', 'UserResolvable');
|
||||
if (!userId) throw new TypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
|
||||
if (!options.force) {
|
||||
const cachedUser = this.cache.get(userId);
|
||||
if (cachedUser) return cachedUser;
|
||||
@@ -106,12 +106,19 @@ class GuildMemberManager extends CachedManager {
|
||||
};
|
||||
if (options.roles) {
|
||||
if (!Array.isArray(options.roles) && !(options.roles instanceof Collection)) {
|
||||
throw new TypeError('INVALID_TYPE', 'options.roles', 'Array or Collection of Roles or Snowflakes', true);
|
||||
throw new TypeError(
|
||||
ErrorCodes.InvalidType,
|
||||
'options.roles',
|
||||
'Array or Collection of Roles or Snowflakes',
|
||||
true,
|
||||
);
|
||||
}
|
||||
const resolvedRoles = [];
|
||||
for (const role of options.roles.values()) {
|
||||
const resolvedRole = this.guild.roles.resolveId(role);
|
||||
if (!resolvedRole) throw new TypeError('INVALID_ELEMENT', 'Array or Collection', 'options.roles', role);
|
||||
if (!resolvedRole) {
|
||||
throw new TypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'options.roles', role);
|
||||
}
|
||||
resolvedRoles.push(resolvedRole);
|
||||
}
|
||||
resolvedOptions.roles = resolvedRoles;
|
||||
@@ -277,12 +284,12 @@ class GuildMemberManager extends CachedManager {
|
||||
*/
|
||||
async edit(user, { reason, ...data }) {
|
||||
const id = this.client.users.resolveId(user);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'user', 'UserResolvable');
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
|
||||
|
||||
if (data.channel) {
|
||||
data.channel = this.guild.channels.resolve(data.channel);
|
||||
if (!(data.channel instanceof BaseGuildVoiceChannel)) {
|
||||
throw new Error('GUILD_VOICE_CHANNEL_RESOLVE');
|
||||
throw new Error(ErrorCodes.GuildVoiceChannelResolve);
|
||||
}
|
||||
data.channel_id = data.channel.id;
|
||||
data.channel = undefined;
|
||||
@@ -346,7 +353,7 @@ class GuildMemberManager extends CachedManager {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async prune({ days, dry = false, count: compute_prune_count, roles = [], reason } = {}) {
|
||||
if (typeof days !== 'number') throw new TypeError('PRUNE_DAYS_TYPE');
|
||||
if (typeof days !== 'number') throw new TypeError(ErrorCodes.PruneDaysType);
|
||||
|
||||
const query = { days };
|
||||
const resolvedRoles = [];
|
||||
@@ -354,7 +361,7 @@ class GuildMemberManager extends CachedManager {
|
||||
for (const role of roles) {
|
||||
const resolvedRole = this.guild.roles.resolveId(role);
|
||||
if (!resolvedRole) {
|
||||
throw new TypeError('INVALID_ELEMENT', 'Array', 'options.roles', role);
|
||||
throw new TypeError(ErrorCodes.InvalidElement, 'Array', 'options.roles', role);
|
||||
}
|
||||
resolvedRoles.push(resolvedRole);
|
||||
}
|
||||
@@ -388,7 +395,7 @@ class GuildMemberManager extends CachedManager {
|
||||
*/
|
||||
async kick(user, reason) {
|
||||
const id = this.client.users.resolveId(user);
|
||||
if (!id) return Promise.reject(new TypeError('INVALID_TYPE', 'user', 'UserResolvable'));
|
||||
if (!id) return Promise.reject(new TypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable'));
|
||||
|
||||
await this.client.rest.delete(Routes.guildMember(this.guild.id, id), { reason });
|
||||
|
||||
@@ -448,7 +455,7 @@ class GuildMemberManager extends CachedManager {
|
||||
} = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!query && !user_ids) query = '';
|
||||
if (nonce.length > 32) throw new RangeError('MEMBER_FETCH_NONCE_LENGTH');
|
||||
if (nonce.length > 32) throw new RangeError(ErrorCodes.MemberFetchNonceLength);
|
||||
this.guild.shard.send({
|
||||
op: GatewayOpcodes.RequestGuildMembers,
|
||||
d: {
|
||||
@@ -481,7 +488,7 @@ class GuildMemberManager extends CachedManager {
|
||||
const timeout = setTimeout(() => {
|
||||
this.client.removeListener(Events.GuildMembersChunk, handler);
|
||||
this.client.decrementMaxListeners();
|
||||
reject(new Error('GUILD_MEMBERS_TIMEOUT'));
|
||||
reject(new Error(ErrorCodes.GuildMembersTimeout));
|
||||
}, time).unref();
|
||||
this.client.incrementMaxListeners();
|
||||
this.client.on(Events.GuildMembersChunk, handler);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const DataManager = require('./DataManager');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const { Role } = require('../structures/Role');
|
||||
|
||||
/**
|
||||
@@ -110,7 +110,7 @@ class GuildMemberRoleManager extends DataManager {
|
||||
const resolvedRoles = [];
|
||||
for (const role of roleOrRoles.values()) {
|
||||
const resolvedRole = this.guild.roles.resolveId(role);
|
||||
if (!resolvedRole) throw new TypeError('INVALID_ELEMENT', 'Array or Collection', 'roles', role);
|
||||
if (!resolvedRole) throw new TypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role);
|
||||
resolvedRoles.push(resolvedRole);
|
||||
}
|
||||
|
||||
@@ -119,7 +119,11 @@ class GuildMemberRoleManager extends DataManager {
|
||||
} else {
|
||||
roleOrRoles = this.guild.roles.resolveId(roleOrRoles);
|
||||
if (roleOrRoles === null) {
|
||||
throw new TypeError('INVALID_TYPE', 'roles', 'Role, Snowflake or Array or Collection of Roles or Snowflakes');
|
||||
throw new TypeError(
|
||||
ErrorCodes.InvalidType,
|
||||
'roles',
|
||||
'Role, Snowflake or Array or Collection of Roles or Snowflakes',
|
||||
);
|
||||
}
|
||||
|
||||
await this.client.rest.put(Routes.guildMemberRole(this.guild.id, this.member.id, roleOrRoles), { reason });
|
||||
@@ -141,7 +145,7 @@ class GuildMemberRoleManager extends DataManager {
|
||||
const resolvedRoles = [];
|
||||
for (const role of roleOrRoles.values()) {
|
||||
const resolvedRole = this.guild.roles.resolveId(role);
|
||||
if (!resolvedRole) throw new TypeError('INVALID_ELEMENT', 'Array or Collection', 'roles', role);
|
||||
if (!resolvedRole) throw new TypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role);
|
||||
resolvedRoles.push(resolvedRole);
|
||||
}
|
||||
|
||||
@@ -150,7 +154,11 @@ class GuildMemberRoleManager extends DataManager {
|
||||
} else {
|
||||
roleOrRoles = this.guild.roles.resolveId(roleOrRoles);
|
||||
if (roleOrRoles === null) {
|
||||
throw new TypeError('INVALID_TYPE', 'roles', 'Role, Snowflake or Array or Collection of Roles or Snowflakes');
|
||||
throw new TypeError(
|
||||
ErrorCodes.InvalidType,
|
||||
'roles',
|
||||
'Role, Snowflake or Array or Collection of Roles or Snowflakes',
|
||||
);
|
||||
}
|
||||
|
||||
await this.client.rest.delete(Routes.guildMemberRole(this.guild.id, this.member.id, roleOrRoles), { reason });
|
||||
|
||||
@@ -4,7 +4,7 @@ const { Collection } = require('@discordjs/collection');
|
||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { GuildScheduledEventEntityType, Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError, Error } = require('../errors');
|
||||
const { TypeError, Error, ErrorCodes } = require('../errors');
|
||||
const { GuildScheduledEvent } = require('../structures/GuildScheduledEvent');
|
||||
const DataResolver = require('../util/DataResolver');
|
||||
|
||||
@@ -69,7 +69,7 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
* @returns {Promise<GuildScheduledEvent>}
|
||||
*/
|
||||
async create(options) {
|
||||
if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true);
|
||||
if (typeof options !== 'object') throw new TypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
||||
let {
|
||||
privacyLevel,
|
||||
entityType,
|
||||
@@ -89,7 +89,7 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
entity_metadata = { location: entityMetadata?.location };
|
||||
} else {
|
||||
channel_id = this.guild.channels.resolveId(channel);
|
||||
if (!channel_id) throw new Error('GUILD_VOICE_CHANNEL_RESOLVE');
|
||||
if (!channel_id) throw new Error(ErrorCodes.GuildVoiceChannelResolve);
|
||||
entity_metadata = typeof entityMetadata === 'undefined' ? entityMetadata : null;
|
||||
}
|
||||
|
||||
@@ -188,9 +188,9 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
*/
|
||||
async edit(guildScheduledEvent, options) {
|
||||
const guildScheduledEventId = this.resolveId(guildScheduledEvent);
|
||||
if (!guildScheduledEventId) throw new Error('GUILD_SCHEDULED_EVENT_RESOLVE');
|
||||
if (!guildScheduledEventId) throw new Error(ErrorCodes.GuildScheduledEventResolve);
|
||||
|
||||
if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true);
|
||||
if (typeof options !== 'object') throw new TypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
||||
let {
|
||||
privacyLevel,
|
||||
entityType,
|
||||
@@ -238,7 +238,7 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
*/
|
||||
async delete(guildScheduledEvent) {
|
||||
const guildScheduledEventId = this.resolveId(guildScheduledEvent);
|
||||
if (!guildScheduledEventId) throw new Error('GUILD_SCHEDULED_EVENT_RESOLVE');
|
||||
if (!guildScheduledEventId) throw new Error(ErrorCodes.GuildScheduledEventResolve);
|
||||
|
||||
await this.client.rest.delete(Routes.guildScheduledEvent(this.guild.id, guildScheduledEventId));
|
||||
}
|
||||
@@ -269,7 +269,7 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
*/
|
||||
async fetchSubscribers(guildScheduledEvent, options = {}) {
|
||||
const guildScheduledEventId = this.resolveId(guildScheduledEvent);
|
||||
if (!guildScheduledEventId) throw new Error('GUILD_SCHEDULED_EVENT_RESOLVE');
|
||||
if (!guildScheduledEventId) throw new Error(ErrorCodes.GuildScheduledEventResolve);
|
||||
|
||||
const query = makeURLSearchParams({
|
||||
limit: options.limit,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const MessagePayload = require('../structures/MessagePayload');
|
||||
const { Sticker } = require('../structures/Sticker');
|
||||
|
||||
@@ -59,7 +59,7 @@ class GuildStickerManager extends CachedManager {
|
||||
*/
|
||||
async create({ file, name, tags, description, reason } = {}) {
|
||||
const resolvedFile = await MessagePayload.resolveFile(file);
|
||||
if (!resolvedFile) throw new TypeError('REQ_RESOURCE_TYPE');
|
||||
if (!resolvedFile) throw new TypeError(ErrorCodes.ReqResourceType);
|
||||
file = { ...resolvedFile, key: 'file' };
|
||||
|
||||
const body = { name, tags, description: description ?? '' };
|
||||
@@ -106,7 +106,7 @@ class GuildStickerManager extends CachedManager {
|
||||
*/
|
||||
async edit(sticker, data = {}) {
|
||||
const stickerId = this.resolveId(sticker);
|
||||
if (!stickerId) throw new TypeError('INVALID_TYPE', 'sticker', 'StickerResolvable');
|
||||
if (!stickerId) throw new TypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
|
||||
|
||||
const d = await this.client.rest.patch(Routes.guildSticker(this.guild.id, stickerId), {
|
||||
body: data,
|
||||
@@ -130,7 +130,7 @@ class GuildStickerManager extends CachedManager {
|
||||
*/
|
||||
async delete(sticker, reason) {
|
||||
sticker = this.resolveId(sticker);
|
||||
if (!sticker) throw new TypeError('INVALID_TYPE', 'sticker', 'StickerResolvable');
|
||||
if (!sticker) throw new TypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
|
||||
|
||||
await this.client.rest.delete(Routes.guildSticker(this.guild.id, sticker), { reason });
|
||||
}
|
||||
@@ -172,7 +172,7 @@ class GuildStickerManager extends CachedManager {
|
||||
*/
|
||||
async fetchUser(sticker) {
|
||||
sticker = this.resolve(sticker);
|
||||
if (!sticker) throw new TypeError('INVALID_TYPE', 'sticker', 'StickerResolvable');
|
||||
if (!sticker) throw new TypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
|
||||
const data = await this.client.rest.get(Routes.guildSticker(this.guild.id, sticker.id));
|
||||
sticker._patch(data);
|
||||
return sticker.user;
|
||||
|
||||
@@ -4,7 +4,7 @@ const { Collection } = require('@discordjs/collection');
|
||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const { Message } = require('../structures/Message');
|
||||
const MessagePayload = require('../structures/MessagePayload');
|
||||
const { resolvePartialEmoji } = require('../util/Util');
|
||||
@@ -155,7 +155,7 @@ class MessageManager extends CachedManager {
|
||||
*/
|
||||
async edit(message, options) {
|
||||
const messageId = this.resolveId(message);
|
||||
if (!messageId) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');
|
||||
if (!messageId) throw new TypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
||||
|
||||
const { body, files } = await (options instanceof MessagePayload
|
||||
? options
|
||||
@@ -181,7 +181,7 @@ class MessageManager extends CachedManager {
|
||||
*/
|
||||
async crosspost(message) {
|
||||
message = this.resolveId(message);
|
||||
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');
|
||||
if (!message) throw new TypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
||||
|
||||
const data = await this.client.rest.post(Routes.channelMessageCrosspost(this.channel.id, message));
|
||||
return this.cache.get(data.id) ?? this._add(data);
|
||||
@@ -195,7 +195,7 @@ class MessageManager extends CachedManager {
|
||||
*/
|
||||
async pin(message, reason) {
|
||||
message = this.resolveId(message);
|
||||
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');
|
||||
if (!message) throw new TypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
||||
|
||||
await this.client.rest.put(Routes.channelPin(this.channel.id, message), { reason });
|
||||
}
|
||||
@@ -208,7 +208,7 @@ class MessageManager extends CachedManager {
|
||||
*/
|
||||
async unpin(message, reason) {
|
||||
message = this.resolveId(message);
|
||||
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');
|
||||
if (!message) throw new TypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
||||
|
||||
await this.client.rest.delete(Routes.channelPin(this.channel.id, message), { reason });
|
||||
}
|
||||
@@ -221,10 +221,10 @@ class MessageManager extends CachedManager {
|
||||
*/
|
||||
async react(message, emoji) {
|
||||
message = this.resolveId(message);
|
||||
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');
|
||||
if (!message) throw new TypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
||||
|
||||
emoji = resolvePartialEmoji(emoji);
|
||||
if (!emoji) throw new TypeError('EMOJI_TYPE', 'emoji', 'EmojiIdentifierResolvable');
|
||||
if (!emoji) throw new TypeError(ErrorCodes.EmojiType, 'emoji', 'EmojiIdentifierResolvable');
|
||||
|
||||
const emojiId = emoji.id
|
||||
? `${emoji.animated ? 'a:' : ''}${emoji.name}:${emoji.id}`
|
||||
@@ -240,7 +240,7 @@ class MessageManager extends CachedManager {
|
||||
*/
|
||||
async delete(message) {
|
||||
message = this.resolveId(message);
|
||||
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');
|
||||
if (!message) throw new TypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
|
||||
|
||||
await this.client.rest.delete(Routes.channelMessage(this.channel.id, message));
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ const process = require('node:process');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { OverwriteType, Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const PermissionOverwrites = require('../structures/PermissionOverwrites');
|
||||
const { Role } = require('../structures/Role');
|
||||
|
||||
@@ -65,7 +65,7 @@ class PermissionOverwriteManager extends CachedManager {
|
||||
set(overwrites, reason) {
|
||||
if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) {
|
||||
return Promise.reject(
|
||||
new TypeError('INVALID_TYPE', 'overwrites', 'Array or Collection of Permission Overwrites', true),
|
||||
new TypeError(ErrorCodes.InvalidType, 'overwrites', 'Array or Collection of Permission Overwrites', true),
|
||||
);
|
||||
}
|
||||
return this.channel.edit({ permissionOverwrites: overwrites, reason });
|
||||
@@ -93,7 +93,7 @@ class PermissionOverwriteManager extends CachedManager {
|
||||
let { type, reason } = overwriteOptions;
|
||||
if (typeof type !== 'number') {
|
||||
userOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole);
|
||||
if (!userOrRole) throw new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role');
|
||||
if (!userOrRole) throw new TypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role');
|
||||
type = userOrRole instanceof Role ? OverwriteType.Role : OverwriteType.Member;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ class PermissionOverwriteManager extends CachedManager {
|
||||
*/
|
||||
async delete(userOrRole, reason) {
|
||||
const userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole);
|
||||
if (!userOrRoleId) throw new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role');
|
||||
if (!userOrRoleId) throw new TypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role');
|
||||
|
||||
await this.client.rest.delete(Routes.channelPermission(this.channel.id, userOrRoleId), { reason });
|
||||
return this.channel;
|
||||
|
||||
@@ -4,7 +4,7 @@ const { Collection } = require('@discordjs/collection');
|
||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const User = require('../structures/User');
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ class ReactionUserManager extends CachedManager {
|
||||
*/
|
||||
async remove(user = this.client.user) {
|
||||
const userId = this.client.users.resolveId(user);
|
||||
if (!userId) throw new Error('REACTION_RESOLVE_USER');
|
||||
if (!userId) throw new Error(ErrorCodes.ReactionResolveUser);
|
||||
const message = this.reaction.message;
|
||||
const route =
|
||||
userId === this.client.user.id
|
||||
|
||||
@@ -4,7 +4,7 @@ const process = require('node:process');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const { Role } = require('../structures/Role');
|
||||
const DataResolver = require('../util/DataResolver');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
@@ -183,7 +183,7 @@ class RoleManager extends CachedManager {
|
||||
*/
|
||||
async edit(role, data) {
|
||||
role = this.resolve(role);
|
||||
if (!role) throw new TypeError('INVALID_TYPE', 'role', 'RoleResolvable');
|
||||
if (!role) throw new TypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable');
|
||||
|
||||
if (typeof data.position === 'number') {
|
||||
await this.setPosition(role, data.position, { reason: data.reason });
|
||||
@@ -244,7 +244,7 @@ class RoleManager extends CachedManager {
|
||||
*/
|
||||
async setPosition(role, position, { relative, reason } = {}) {
|
||||
role = this.resolve(role);
|
||||
if (!role) throw new TypeError('INVALID_TYPE', 'role', 'RoleResolvable');
|
||||
if (!role) throw new TypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable');
|
||||
const updatedRoles = await setPosition(
|
||||
role,
|
||||
position,
|
||||
@@ -303,7 +303,7 @@ class RoleManager extends CachedManager {
|
||||
comparePositions(role1, role2) {
|
||||
const resolvedRole1 = this.resolve(role1);
|
||||
const resolvedRole2 = this.resolve(role2);
|
||||
if (!resolvedRole1 || !resolvedRole2) throw new TypeError('INVALID_TYPE', 'role', 'Role nor a Snowflake');
|
||||
if (!resolvedRole1 || !resolvedRole2) throw new TypeError(ErrorCodes.InvalidType, 'role', 'Role nor a Snowflake');
|
||||
|
||||
if (resolvedRole1.position === resolvedRole2.position) {
|
||||
return Number(BigInt(resolvedRole2.id) - BigInt(resolvedRole1.id));
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError, Error } = require('../errors');
|
||||
const { TypeError, Error, ErrorCodes } = require('../errors');
|
||||
const { StageInstance } = require('../structures/StageInstance');
|
||||
|
||||
/**
|
||||
@@ -57,8 +57,8 @@ class StageInstanceManager extends CachedManager {
|
||||
*/
|
||||
async create(channel, options) {
|
||||
const channelId = this.guild.channels.resolveId(channel);
|
||||
if (!channelId) throw new Error('STAGE_CHANNEL_RESOLVE');
|
||||
if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true);
|
||||
if (!channelId) throw new Error(ErrorCodes.StageChannelResolve);
|
||||
if (typeof options !== 'object') throw new TypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
||||
let { topic, privacyLevel, sendStartNotification } = options;
|
||||
|
||||
const data = await this.client.rest.post(Routes.stageInstances(), {
|
||||
@@ -86,7 +86,7 @@ class StageInstanceManager extends CachedManager {
|
||||
*/
|
||||
async fetch(channel, { cache = true, force = false } = {}) {
|
||||
const channelId = this.guild.channels.resolveId(channel);
|
||||
if (!channelId) throw new Error('STAGE_CHANNEL_RESOLVE');
|
||||
if (!channelId) throw new Error(ErrorCodes.StageChannelResolve);
|
||||
|
||||
if (!force) {
|
||||
const existing = this.cache.find(stageInstance => stageInstance.channelId === channelId);
|
||||
@@ -116,9 +116,9 @@ class StageInstanceManager extends CachedManager {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async edit(channel, options) {
|
||||
if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true);
|
||||
if (typeof options !== 'object') throw new TypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
||||
const channelId = this.guild.channels.resolveId(channel);
|
||||
if (!channelId) throw new Error('STAGE_CHANNEL_RESOLVE');
|
||||
if (!channelId) throw new Error(ErrorCodes.StageChannelResolve);
|
||||
|
||||
let { topic, privacyLevel } = options;
|
||||
|
||||
@@ -145,7 +145,7 @@ class StageInstanceManager extends CachedManager {
|
||||
*/
|
||||
async delete(channel) {
|
||||
const channelId = this.guild.channels.resolveId(channel);
|
||||
if (!channelId) throw new Error('STAGE_CHANNEL_RESOLVE');
|
||||
if (!channelId) throw new Error(ErrorCodes.StageChannelResolve);
|
||||
|
||||
await this.client.rest.delete(Routes.stageInstance(channelId));
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ const { Collection } = require('@discordjs/collection');
|
||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { ChannelType, Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const ThreadChannel = require('../structures/ThreadChannel');
|
||||
|
||||
/**
|
||||
@@ -110,14 +110,14 @@ class ThreadManager extends CachedManager {
|
||||
rateLimitPerUser,
|
||||
} = {}) {
|
||||
if (type && typeof type !== 'string' && typeof type !== 'number') {
|
||||
throw new TypeError('INVALID_TYPE', 'type', 'ThreadChannelType or Number');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'type', 'ThreadChannelType or Number');
|
||||
}
|
||||
let resolvedType =
|
||||
this.channel.type === ChannelType.GuildNews ? ChannelType.GuildNewsThread : ChannelType.GuildPublicThread;
|
||||
let startMessageId;
|
||||
if (startMessage) {
|
||||
startMessageId = this.channel.messages.resolveId(startMessage);
|
||||
if (!startMessageId) throw new TypeError('INVALID_TYPE', 'startMessage', 'MessageResolvable');
|
||||
if (!startMessageId) throw new TypeError(ErrorCodes.InvalidType, 'startMessage', 'MessageResolvable');
|
||||
} else if (this.channel.type !== ChannelType.GuildNews) {
|
||||
resolvedType = type ?? resolvedType;
|
||||
}
|
||||
@@ -221,7 +221,7 @@ class ThreadManager extends CachedManager {
|
||||
query.set('before', timestamp);
|
||||
}
|
||||
} catch {
|
||||
throw new TypeError('INVALID_TYPE', 'before', 'DateResolvable or ThreadChannelResolvable');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'before', 'DateResolvable or ThreadChannelResolvable');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const ThreadMember = require('../structures/ThreadMember');
|
||||
|
||||
/**
|
||||
@@ -95,7 +95,7 @@ class ThreadMemberManager extends CachedManager {
|
||||
*/
|
||||
async add(member, reason) {
|
||||
const id = member === '@me' ? member : this.client.users.resolveId(member);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'member', 'UserResolvable');
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'member', 'UserResolvable');
|
||||
await this.client.rest.put(Routes.threadMembers(this.thread.id, id), { reason });
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
const { ChannelType, Routes } = require('discord-api-types/v10');
|
||||
const CachedManager = require('./CachedManager');
|
||||
const { ErrorCodes } = require('../errors');
|
||||
const { GuildMember } = require('../structures/GuildMember');
|
||||
const { Message } = require('../structures/Message');
|
||||
const ThreadMember = require('../structures/ThreadMember');
|
||||
@@ -68,7 +69,7 @@ class UserManager extends CachedManager {
|
||||
async deleteDM(user) {
|
||||
const id = this.resolveId(user);
|
||||
const dmChannel = this.dmChannel(id);
|
||||
if (!dmChannel) throw new Error('USER_NO_DM_CHANNEL');
|
||||
if (!dmChannel) throw new Error(ErrorCodes.UserNoDMChannel);
|
||||
await this.client.rest.delete(Routes.channel(dmChannel.id));
|
||||
this.client.channels._remove(dmChannel.id);
|
||||
return dmChannel;
|
||||
|
||||
@@ -5,7 +5,7 @@ const path = require('node:path');
|
||||
const process = require('node:process');
|
||||
const { setTimeout, clearTimeout } = require('node:timers');
|
||||
const { setTimeout: sleep } = require('node:timers/promises');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const { makeError, makePlainError } = require('../util/Util');
|
||||
let childProcess = null;
|
||||
let Worker = null;
|
||||
@@ -106,8 +106,8 @@ class Shard extends EventEmitter {
|
||||
* @returns {Promise<ChildProcess>}
|
||||
*/
|
||||
spawn(timeout = 30_000) {
|
||||
if (this.process) throw new Error('SHARDING_PROCESS_EXISTS', this.id);
|
||||
if (this.worker) throw new Error('SHARDING_WORKER_EXISTS', this.id);
|
||||
if (this.process) throw new Error(ErrorCodes.ShardingProcessExists, this.id);
|
||||
if (this.worker) throw new Error(ErrorCodes.ShardingWorkerExists, this.id);
|
||||
|
||||
this._exitListener = this._handleExit.bind(this, undefined, timeout);
|
||||
|
||||
@@ -153,17 +153,17 @@ class Shard extends EventEmitter {
|
||||
|
||||
const onDisconnect = () => {
|
||||
cleanup();
|
||||
reject(new Error('SHARDING_READY_DISCONNECTED', this.id));
|
||||
reject(new Error(ErrorCodes.ShardingReadyDisconnected, this.id));
|
||||
};
|
||||
|
||||
const onDeath = () => {
|
||||
cleanup();
|
||||
reject(new Error('SHARDING_READY_DIED', this.id));
|
||||
reject(new Error(ErrorCodes.ShardingReadyDied, this.id));
|
||||
};
|
||||
|
||||
const onTimeout = () => {
|
||||
cleanup();
|
||||
reject(new Error('SHARDING_READY_TIMEOUT', this.id));
|
||||
reject(new Error(ErrorCodes.ShardingReadyTimeout, this.id));
|
||||
};
|
||||
|
||||
const spawnTimeoutTimer = setTimeout(onTimeout, timeout);
|
||||
@@ -238,7 +238,7 @@ class Shard extends EventEmitter {
|
||||
*/
|
||||
fetchClientValue(prop) {
|
||||
// Shard is dead (maybe respawning), don't cache anything and error immediately
|
||||
if (!this.process && !this.worker) return Promise.reject(new Error('SHARDING_NO_CHILD_EXISTS', this.id));
|
||||
if (!this.process && !this.worker) return Promise.reject(new Error(ErrorCodes.ShardingNoChildExists, this.id));
|
||||
|
||||
// Cached promise from previous call
|
||||
if (this._fetches.has(prop)) return this._fetches.get(prop);
|
||||
@@ -281,7 +281,7 @@ class Shard extends EventEmitter {
|
||||
const _eval = typeof script === 'function' ? `(${script})(this, ${JSON.stringify(context)})` : script;
|
||||
|
||||
// Shard is dead (maybe respawning), don't cache anything and error immediately
|
||||
if (!this.process && !this.worker) return Promise.reject(new Error('SHARDING_NO_CHILD_EXISTS', this.id));
|
||||
if (!this.process && !this.worker) return Promise.reject(new Error(ErrorCodes.ShardingNoChildExists, this.id));
|
||||
|
||||
// Cached promise from previous call
|
||||
if (this._evals.has(_eval)) return this._evals.get(_eval);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const process = require('node:process');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const Events = require('../util/Events');
|
||||
const { makeError, makePlainError } = require('../util/Util');
|
||||
|
||||
@@ -141,7 +141,7 @@ class ShardClientUtil {
|
||||
return new Promise((resolve, reject) => {
|
||||
const parent = this.parentPort ?? process;
|
||||
if (typeof script !== 'function') {
|
||||
reject(new TypeError('SHARDING_INVALID_EVAL_BROADCAST'));
|
||||
reject(new TypeError(ErrorCodes.ShardingInvalidEvalBroadcast));
|
||||
return;
|
||||
}
|
||||
script = `(${script})(this, ${JSON.stringify(options.context)})`;
|
||||
@@ -246,7 +246,7 @@ class ShardClientUtil {
|
||||
*/
|
||||
static shardIdForGuildId(guildId, shardCount) {
|
||||
const shard = Number(BigInt(guildId) >> 22n) % shardCount;
|
||||
if (shard < 0) throw new Error('SHARDING_SHARD_MISCALCULATION', shard, guildId, shardCount);
|
||||
if (shard < 0) throw new Error(ErrorCodes.ShardingShardMiscalculation, shard, guildId, shardCount);
|
||||
return shard;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ const process = require('node:process');
|
||||
const { setTimeout: sleep } = require('node:timers/promises');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const Shard = require('./Shard');
|
||||
const { Error, TypeError, RangeError } = require('../errors');
|
||||
const { Error, TypeError, RangeError, ErrorCodes } = require('../errors');
|
||||
const { mergeDefault, fetchRecommendedShards } = require('../util/Util');
|
||||
|
||||
/**
|
||||
@@ -64,10 +64,10 @@ class ShardingManager extends EventEmitter {
|
||||
* @type {string}
|
||||
*/
|
||||
this.file = file;
|
||||
if (!file) throw new Error('CLIENT_INVALID_OPTION', 'File', 'specified.');
|
||||
if (!file) throw new Error(ErrorCodes.ClientInvalidOption, 'File', 'specified.');
|
||||
if (!path.isAbsolute(file)) this.file = path.resolve(process.cwd(), file);
|
||||
const stats = fs.statSync(this.file);
|
||||
if (!stats.isFile()) throw new Error('CLIENT_INVALID_OPTION', 'File', 'a file');
|
||||
if (!stats.isFile()) throw new Error(ErrorCodes.ClientInvalidOption, 'File', 'a file');
|
||||
|
||||
/**
|
||||
* List of shards this sharding manager spawns
|
||||
@@ -76,16 +76,18 @@ class ShardingManager extends EventEmitter {
|
||||
this.shardList = options.shardList ?? 'auto';
|
||||
if (this.shardList !== 'auto') {
|
||||
if (!Array.isArray(this.shardList)) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'shardList', 'an array.');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'shardList', 'an array.');
|
||||
}
|
||||
this.shardList = [...new Set(this.shardList)];
|
||||
if (this.shardList.length < 1) throw new RangeError('CLIENT_INVALID_OPTION', 'shardList', 'at least 1 id.');
|
||||
if (this.shardList.length < 1) {
|
||||
throw new RangeError(ErrorCodes.ClientInvalidOption, 'shardList', 'at least 1 id.');
|
||||
}
|
||||
if (
|
||||
this.shardList.some(
|
||||
shardId => typeof shardId !== 'number' || isNaN(shardId) || !Number.isInteger(shardId) || shardId < 0,
|
||||
)
|
||||
) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'shardList', 'an array of positive integers.');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'shardList', 'an array of positive integers.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,11 +98,13 @@ class ShardingManager extends EventEmitter {
|
||||
this.totalShards = options.totalShards || 'auto';
|
||||
if (this.totalShards !== 'auto') {
|
||||
if (typeof this.totalShards !== 'number' || isNaN(this.totalShards)) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'Amount of shards', 'a number.');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'a number.');
|
||||
}
|
||||
if (this.totalShards < 1) {
|
||||
throw new RangeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'at least 1.');
|
||||
}
|
||||
if (this.totalShards < 1) throw new RangeError('CLIENT_INVALID_OPTION', 'Amount of shards', 'at least 1.');
|
||||
if (!Number.isInteger(this.totalShards)) {
|
||||
throw new RangeError('CLIENT_INVALID_OPTION', 'Amount of shards', 'an integer.');
|
||||
throw new RangeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'an integer.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +114,7 @@ class ShardingManager extends EventEmitter {
|
||||
*/
|
||||
this.mode = options.mode;
|
||||
if (this.mode !== 'process' && this.mode !== 'worker') {
|
||||
throw new RangeError('CLIENT_INVALID_OPTION', 'Sharding mode', '"process" or "worker"');
|
||||
throw new RangeError(ErrorCodes.ClientInvalidOption, 'Sharding mode', '"process" or "worker"');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,16 +190,16 @@ class ShardingManager extends EventEmitter {
|
||||
amount = await fetchRecommendedShards(this.token);
|
||||
} else {
|
||||
if (typeof amount !== 'number' || isNaN(amount)) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'Amount of shards', 'a number.');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'a number.');
|
||||
}
|
||||
if (amount < 1) throw new RangeError('CLIENT_INVALID_OPTION', 'Amount of shards', 'at least 1.');
|
||||
if (amount < 1) throw new RangeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'at least 1.');
|
||||
if (!Number.isInteger(amount)) {
|
||||
throw new TypeError('CLIENT_INVALID_OPTION', 'Amount of shards', 'an integer.');
|
||||
throw new TypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'an integer.');
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure this many shards haven't already been spawned
|
||||
if (this.shards.size >= amount) throw new Error('SHARDING_ALREADY_SPAWNED', this.shards.size);
|
||||
if (this.shards.size >= amount) throw new Error(ErrorCodes.ShardingAlreadySpawned, this.shards.size);
|
||||
if (this.shardList === 'auto' || this.totalShards === 'auto' || this.totalShards !== amount) {
|
||||
this.shardList = [...Array(amount).keys()];
|
||||
}
|
||||
@@ -205,7 +209,7 @@ class ShardingManager extends EventEmitter {
|
||||
|
||||
if (this.shardList.some(shardId => shardId >= amount)) {
|
||||
throw new RangeError(
|
||||
'CLIENT_INVALID_OPTION',
|
||||
ErrorCodes.ClientInvalidOption,
|
||||
'Amount of shards',
|
||||
'bigger than the highest shardId in the shardList option.',
|
||||
);
|
||||
@@ -248,7 +252,7 @@ class ShardingManager extends EventEmitter {
|
||||
* @returns {Promise<*|Array<*>>} Results of the script execution
|
||||
*/
|
||||
broadcastEval(script, options = {}) {
|
||||
if (typeof script !== 'function') return Promise.reject(new TypeError('SHARDING_INVALID_EVAL_BROADCAST'));
|
||||
if (typeof script !== 'function') return Promise.reject(new TypeError(ErrorCodes.ShardingInvalidEvalBroadcast));
|
||||
return this._performOnShards('eval', [`(${script})(this, ${JSON.stringify(options.context)})`], options.shard);
|
||||
}
|
||||
|
||||
@@ -275,14 +279,14 @@ class ShardingManager extends EventEmitter {
|
||||
* @private
|
||||
*/
|
||||
_performOnShards(method, args, shard) {
|
||||
if (this.shards.size === 0) return Promise.reject(new Error('SHARDING_NO_SHARDS'));
|
||||
if (this.shards.size === 0) return Promise.reject(new Error(ErrorCodes.ShardingNoShards));
|
||||
|
||||
if (typeof shard === 'number') {
|
||||
if (this.shards.has(shard)) return this.shards.get(shard)[method](...args);
|
||||
return Promise.reject(new Error('SHARDING_SHARD_NOT_FOUND', shard));
|
||||
return Promise.reject(new Error(ErrorCodes.ShardingShardNotFound, shard));
|
||||
}
|
||||
|
||||
if (this.shards.size !== this.shardList.length) return Promise.reject(new Error('SHARDING_IN_PROCESS'));
|
||||
if (this.shards.size !== this.shardList.length) return Promise.reject(new Error(ErrorCodes.ShardingInProcess));
|
||||
|
||||
const promises = [];
|
||||
for (const sh of this.shards.values()) promises.push(sh[method](...args));
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
const { InteractionResponseType, Routes } = require('discord-api-types/v10');
|
||||
const CommandInteractionOptionResolver = require('./CommandInteractionOptionResolver');
|
||||
const Interaction = require('./Interaction');
|
||||
const { ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Represents an autocomplete interaction.
|
||||
@@ -80,7 +81,7 @@ class AutocompleteInteraction extends Interaction {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async respond(options) {
|
||||
if (this.responded) throw new Error('INTERACTION_ALREADY_REPLIED');
|
||||
if (this.responded) throw new Error(ErrorCodes.InteractionAlreadyReplied);
|
||||
|
||||
await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
|
||||
body: {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const { GatewayOpcodes } = require('discord-api-types/v10');
|
||||
const { Presence } = require('./Presence');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Represents the client's presence.
|
||||
@@ -48,7 +48,9 @@ class ClientPresence extends Presence {
|
||||
};
|
||||
if (activities?.length) {
|
||||
for (const [i, activity] of activities.entries()) {
|
||||
if (typeof activity.name !== 'string') throw new TypeError('INVALID_TYPE', `activities[${i}].name`, 'string');
|
||||
if (typeof activity.name !== 'string') {
|
||||
throw new TypeError(ErrorCodes.InvalidType, `activities[${i}].name`, 'string');
|
||||
}
|
||||
activity.type ??= 0;
|
||||
|
||||
data.activities.push({
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { ApplicationCommandOptionType } = require('discord-api-types/v10');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* A resolver for command interaction options.
|
||||
@@ -75,7 +75,7 @@ class CommandInteractionOptionResolver {
|
||||
const option = this._hoistedOptions.find(opt => opt.name === name);
|
||||
if (!option) {
|
||||
if (required) {
|
||||
throw new TypeError('COMMAND_INTERACTION_OPTION_NOT_FOUND', name);
|
||||
throw new TypeError(ErrorCodes.CommandInteractionOptionNotFound, name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -96,9 +96,9 @@ class CommandInteractionOptionResolver {
|
||||
if (!option) {
|
||||
return null;
|
||||
} else if (option.type !== type) {
|
||||
throw new TypeError('COMMAND_INTERACTION_OPTION_TYPE', name, option.type, type);
|
||||
throw new TypeError(ErrorCodes.CommandInteractionOptionType, name, option.type, type);
|
||||
} else if (required && properties.every(prop => option[prop] === null || typeof option[prop] === 'undefined')) {
|
||||
throw new TypeError('COMMAND_INTERACTION_OPTION_EMPTY', name, option.type);
|
||||
throw new TypeError(ErrorCodes.CommandInteractionOptionEmpty, name, option.type);
|
||||
}
|
||||
return option;
|
||||
}
|
||||
@@ -110,7 +110,7 @@ class CommandInteractionOptionResolver {
|
||||
*/
|
||||
getSubcommand(required = true) {
|
||||
if (required && !this._subcommand) {
|
||||
throw new TypeError('COMMAND_INTERACTION_OPTION_NO_SUB_COMMAND');
|
||||
throw new TypeError(ErrorCodes.CommandInteractionOptionNoSubcommand);
|
||||
}
|
||||
return this._subcommand;
|
||||
}
|
||||
@@ -122,7 +122,7 @@ class CommandInteractionOptionResolver {
|
||||
*/
|
||||
getSubcommandGroup(required = false) {
|
||||
if (required && !this._group) {
|
||||
throw new TypeError('COMMAND_INTERACTION_OPTION_NO_SUB_COMMAND_GROUP');
|
||||
throw new TypeError(ErrorCodes.CommandInteractionOptionNoSubcommandGroup);
|
||||
}
|
||||
return this._group;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ class CommandInteractionOptionResolver {
|
||||
*/
|
||||
getFocused(getFull = false) {
|
||||
const focusedOption = this._hoistedOptions.find(option => option.focused);
|
||||
if (!focusedOption) throw new TypeError('AUTOCOMPLETE_INTERACTION_OPTION_NO_FOCUSED_OPTION');
|
||||
if (!focusedOption) throw new TypeError(ErrorCodes.AutocompleteInteractionOptionNoFocusedOption);
|
||||
return getFull ? focusedOption : focusedOption.value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ const GuildTemplate = require('./GuildTemplate');
|
||||
const Integration = require('./Integration');
|
||||
const Webhook = require('./Webhook');
|
||||
const WelcomeScreen = require('./WelcomeScreen');
|
||||
const { Error, TypeError } = require('../errors');
|
||||
const { Error, TypeError, ErrorCodes } = require('../errors');
|
||||
const GuildApplicationCommandManager = require('../managers/GuildApplicationCommandManager');
|
||||
const GuildBanManager = require('../managers/GuildBanManager');
|
||||
const GuildChannelManager = require('../managers/GuildChannelManager');
|
||||
@@ -453,7 +453,7 @@ class Guild extends AnonymousGuild {
|
||||
*/
|
||||
async fetchOwner(options) {
|
||||
if (!this.ownerId) {
|
||||
throw new Error('FETCH_OWNER_ID');
|
||||
throw new Error(ErrorCodes.FetchOwnerId);
|
||||
}
|
||||
const member = await this.members.fetch({ ...options, user: this.ownerId });
|
||||
return member;
|
||||
@@ -604,7 +604,7 @@ class Guild extends AnonymousGuild {
|
||||
*/
|
||||
async fetchVanityData() {
|
||||
if (!this.features.includes(GuildFeature.VanityURL)) {
|
||||
throw new Error('VANITY_URL');
|
||||
throw new Error(ErrorCodes.VanityURL);
|
||||
}
|
||||
const data = await this.client.rest.get(Routes.guildVanityUrl(this.id));
|
||||
this.vanityURLCode = data.code;
|
||||
@@ -705,7 +705,7 @@ class Guild extends AnonymousGuild {
|
||||
|
||||
if (options.user) {
|
||||
const id = this.client.users.resolveId(options.user);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'user', 'UserResolvable');
|
||||
if (!id) throw new TypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
|
||||
query.set('user_id', id);
|
||||
}
|
||||
|
||||
@@ -1164,7 +1164,7 @@ class Guild extends AnonymousGuild {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async leave() {
|
||||
if (this.ownerId === this.client.user.id) throw new Error('GUILD_OWNED');
|
||||
if (this.ownerId === this.client.user.id) throw new Error(ErrorCodes.GuildOwned);
|
||||
await this.client.rest.delete(Routes.userGuild(this.id));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const { PermissionFlagsBits } = require('discord-api-types/v10');
|
||||
const { Channel } = require('./Channel');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const PermissionOverwriteManager = require('../managers/PermissionOverwriteManager');
|
||||
const { VoiceBasedChannelTypes } = require('../util/Constants');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
@@ -246,7 +246,7 @@ class GuildChannel extends Channel {
|
||||
* @returns {Promise<GuildChannel>}
|
||||
*/
|
||||
lockPermissions() {
|
||||
if (!this.parent) return Promise.reject(new Error('GUILD_CHANNEL_ORPHAN'));
|
||||
if (!this.parent) return Promise.reject(new Error(ErrorCodes.GuildChannelOrphan));
|
||||
const permissionOverwrites = this.parent.permissionOverwrites.cache.map(overwrite => overwrite.toJSON());
|
||||
return this.edit({ permissionOverwrites });
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const { PermissionFlagsBits } = require('discord-api-types/v10');
|
||||
const BaseGuildEmoji = require('./BaseGuildEmoji');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const GuildEmojiRoleManager = require('../managers/GuildEmojiRoleManager');
|
||||
|
||||
/**
|
||||
@@ -55,7 +55,7 @@ class GuildEmoji extends BaseGuildEmoji {
|
||||
* @readonly
|
||||
*/
|
||||
get deletable() {
|
||||
if (!this.guild.members.me) throw new Error('GUILD_UNCACHED_ME');
|
||||
if (!this.guild.members.me) throw new Error(ErrorCodes.GuildUncachedMe);
|
||||
return !this.managed && this.guild.members.me.permissions.has(PermissionFlagsBits.ManageEmojisAndStickers);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ const { PermissionFlagsBits } = require('discord-api-types/v10');
|
||||
const Base = require('./Base');
|
||||
const VoiceState = require('./VoiceState');
|
||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const GuildMemberRoleManager = require('../managers/GuildMemberRoleManager');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
|
||||
@@ -239,7 +239,7 @@ class GuildMember extends Base {
|
||||
if (this.user.id === this.guild.ownerId) return false;
|
||||
if (this.user.id === this.client.user.id) return false;
|
||||
if (this.client.user.id === this.guild.ownerId) return true;
|
||||
if (!this.guild.members.me) throw new Error('GUILD_UNCACHED_ME');
|
||||
if (!this.guild.members.me) throw new Error(ErrorCodes.GuildUncachedMe);
|
||||
return this.guild.members.me.roles.highest.comparePositionTo(this.roles.highest) > 0;
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ class GuildMember extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get kickable() {
|
||||
if (!this.guild.members.me) throw new Error('GUILD_UNCACHED_ME');
|
||||
if (!this.guild.members.me) throw new Error(ErrorCodes.GuildUncachedMe);
|
||||
return this.manageable && this.guild.members.me.permissions.has(PermissionFlagsBits.KickMembers);
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ class GuildMember extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get bannable() {
|
||||
if (!this.guild.members.me) throw new Error('GUILD_UNCACHED_ME');
|
||||
if (!this.guild.members.me) throw new Error(ErrorCodes.GuildUncachedMe);
|
||||
return this.manageable && this.guild.members.me.permissions.has(PermissionFlagsBits.BanMembers);
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ class GuildMember extends Base {
|
||||
*/
|
||||
permissionsIn(channel) {
|
||||
channel = this.guild.channels.resolve(channel);
|
||||
if (!channel) throw new Error('GUILD_CHANNEL_RESOLVE');
|
||||
if (!channel) throw new Error(ErrorCodes.GuildChannelResolve);
|
||||
return channel.permissionsFor(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { GuildScheduledEventStatus, GuildScheduledEventEntityType, RouteBases } = require('discord-api-types/v10');
|
||||
const Base = require('./Base');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Represents a scheduled event in a {@link Guild}.
|
||||
@@ -253,9 +253,9 @@ class GuildScheduledEvent extends Base {
|
||||
async createInviteURL(options) {
|
||||
let channelId = this.channelId;
|
||||
if (this.entityType === GuildScheduledEventEntityType.External) {
|
||||
if (!options?.channel) throw new Error('INVITE_OPTIONS_MISSING_CHANNEL');
|
||||
if (!options?.channel) throw new Error(ErrorCodes.InviteOptionsMissingChannel);
|
||||
channelId = this.guild.channels.resolveId(options.channel);
|
||||
if (!channelId) throw new Error('GUILD_CHANNEL_RESOLVE');
|
||||
if (!channelId) throw new Error(ErrorCodes.GuildChannelResolve);
|
||||
}
|
||||
const invite = await this.guild.invites.create(channelId, options);
|
||||
return `${RouteBases.invite}/${invite.code}?event=${this.id}`;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { InteractionType } = require('discord-api-types/v10');
|
||||
const { ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Represents an interaction's response
|
||||
@@ -38,7 +39,7 @@ class InteractionResponse {
|
||||
collector.once('end', (interactions, reason) => {
|
||||
const interaction = interactions.first();
|
||||
if (interaction) resolve(interaction);
|
||||
else reject(new Error('INTERACTION_COLLECTOR_ERROR', reason));
|
||||
else reject(new Error(ErrorCodes.InteractionCollectorError, reason));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -57,5 +58,6 @@ class InteractionResponse {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line import/order
|
||||
const InteractionCollector = require('./InteractionCollector');
|
||||
module.exports = InteractionResponse;
|
||||
|
||||
@@ -5,7 +5,7 @@ const Base = require('./Base');
|
||||
const { GuildScheduledEvent } = require('./GuildScheduledEvent');
|
||||
const IntegrationApplication = require('./IntegrationApplication');
|
||||
const InviteStageInstance = require('./InviteStageInstance');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Represents an invitation to a guild channel.
|
||||
@@ -233,7 +233,7 @@ class Invite extends Base {
|
||||
get deletable() {
|
||||
const guild = this.guild;
|
||||
if (!guild || !this.client.guilds.cache.has(guild.id)) return false;
|
||||
if (!guild.members.me) throw new Error('GUILD_UNCACHED_ME');
|
||||
if (!guild.members.me) throw new Error(ErrorCodes.GuildUncachedMe);
|
||||
return Boolean(
|
||||
this.channel?.permissionsFor(this.client.user).has(PermissionFlagsBits.ManageChannels, false) ||
|
||||
guild.members.me.permissions.has(PermissionFlagsBits.ManageGuild),
|
||||
|
||||
@@ -18,7 +18,7 @@ const Mentions = require('./MessageMentions');
|
||||
const MessagePayload = require('./MessagePayload');
|
||||
const ReactionCollector = require('./ReactionCollector');
|
||||
const { Sticker } = require('./Sticker');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const ReactionManager = require('../managers/ReactionManager');
|
||||
const { createComponent } = require('../util/Components');
|
||||
const { NonSystemMessageTypes } = require('../util/Constants');
|
||||
@@ -541,7 +541,7 @@ class Message extends Base {
|
||||
collector.once('end', (interactions, reason) => {
|
||||
const interaction = interactions.first();
|
||||
if (interaction) resolve(interaction);
|
||||
else reject(new Error('INTERACTION_COLLECTOR_ERROR', reason));
|
||||
else reject(new Error(ErrorCodes.InteractionCollectorError, reason));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -607,10 +607,10 @@ class Message extends Base {
|
||||
* @returns {Promise<Message>}
|
||||
*/
|
||||
async fetchReference() {
|
||||
if (!this.reference) throw new Error('MESSAGE_REFERENCE_MISSING');
|
||||
if (!this.reference) throw new Error(ErrorCodes.MessageReferenceMissing);
|
||||
const { channelId, messageId } = this.reference;
|
||||
const channel = this.client.channels.resolve(channelId);
|
||||
if (!channel) throw new Error('GUILD_CHANNEL_RESOLVE');
|
||||
if (!channel) throw new Error(ErrorCodes.GuildChannelResolve);
|
||||
const message = await channel.messages.fetch(messageId);
|
||||
return message;
|
||||
}
|
||||
@@ -661,7 +661,7 @@ class Message extends Base {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
edit(options) {
|
||||
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
|
||||
if (!this.channel) return Promise.reject(new Error(ErrorCodes.ChannelNotCached));
|
||||
return this.channel.messages.edit(this, options);
|
||||
}
|
||||
|
||||
@@ -677,7 +677,7 @@ class Message extends Base {
|
||||
* }
|
||||
*/
|
||||
crosspost() {
|
||||
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
|
||||
if (!this.channel) return Promise.reject(new Error(ErrorCodes.ChannelNotCached));
|
||||
return this.channel.messages.crosspost(this.id);
|
||||
}
|
||||
|
||||
@@ -692,7 +692,7 @@ class Message extends Base {
|
||||
* .catch(console.error)
|
||||
*/
|
||||
async pin(reason) {
|
||||
if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
|
||||
if (!this.channel) throw new Error(ErrorCodes.ChannelNotCached);
|
||||
await this.channel.messages.pin(this.id, reason);
|
||||
return this;
|
||||
}
|
||||
@@ -708,7 +708,7 @@ class Message extends Base {
|
||||
* .catch(console.error)
|
||||
*/
|
||||
async unpin(reason) {
|
||||
if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
|
||||
if (!this.channel) throw new Error(ErrorCodes.ChannelNotCached);
|
||||
await this.channel.messages.unpin(this.id, reason);
|
||||
return this;
|
||||
}
|
||||
@@ -729,7 +729,7 @@ class Message extends Base {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async react(emoji) {
|
||||
if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
|
||||
if (!this.channel) throw new Error(ErrorCodes.ChannelNotCached);
|
||||
await this.channel.messages.react(this.id, emoji);
|
||||
|
||||
return this.client.actions.MessageReactionAdd.handle(
|
||||
@@ -753,7 +753,7 @@ class Message extends Base {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async delete() {
|
||||
if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
|
||||
if (!this.channel) throw new Error(ErrorCodes.ChannelNotCached);
|
||||
await this.channel.messages.delete(this.id);
|
||||
return this;
|
||||
}
|
||||
@@ -777,7 +777,7 @@ class Message extends Base {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
reply(options) {
|
||||
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
|
||||
if (!this.channel) return Promise.reject(new Error(ErrorCodes.ChannelNotCached));
|
||||
let data;
|
||||
|
||||
if (options instanceof MessagePayload) {
|
||||
@@ -820,11 +820,11 @@ class Message extends Base {
|
||||
* @returns {Promise<ThreadChannel>}
|
||||
*/
|
||||
startThread(options = {}) {
|
||||
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
|
||||
if (!this.channel) return Promise.reject(new Error(ErrorCodes.ChannelNotCached));
|
||||
if (![ChannelType.GuildText, ChannelType.GuildNews].includes(this.channel.type)) {
|
||||
return Promise.reject(new Error('MESSAGE_THREAD_PARENT'));
|
||||
return Promise.reject(new Error(ErrorCodes.MessageThreadParent));
|
||||
}
|
||||
if (this.hasThread) return Promise.reject(new Error('MESSAGE_EXISTING_THREAD'));
|
||||
if (this.hasThread) return Promise.reject(new Error(ErrorCodes.MessageExistingThread));
|
||||
return this.channel.threads.create({ ...options, startMessage: this });
|
||||
}
|
||||
|
||||
@@ -834,7 +834,7 @@ class Message extends Base {
|
||||
* @returns {Promise<Message>}
|
||||
*/
|
||||
fetch(force = true) {
|
||||
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED'));
|
||||
if (!this.channel) return Promise.reject(new Error(ErrorCodes.ChannelNotCached));
|
||||
return this.channel.messages.fetch({ message: this.id, force });
|
||||
}
|
||||
|
||||
@@ -843,8 +843,8 @@ class Message extends Base {
|
||||
* @returns {Promise<?Webhook>}
|
||||
*/
|
||||
fetchWebhook() {
|
||||
if (!this.webhookId) return Promise.reject(new Error('WEBHOOK_MESSAGE'));
|
||||
if (this.webhookId === this.applicationId) return Promise.reject(new Error('WEBHOOK_APPLICATION'));
|
||||
if (!this.webhookId) return Promise.reject(new Error(ErrorCodes.WebhookMessage));
|
||||
if (this.webhookId === this.applicationId) return Promise.reject(new Error(ErrorCodes.WebhookApplication));
|
||||
return this.client.fetchWebhook(this.webhookId);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ const { Buffer } = require('node:buffer');
|
||||
const { isJSONEncodable } = require('@discordjs/builders');
|
||||
const { MessageFlags } = require('discord-api-types/v10');
|
||||
const ActionRowBuilder = require('./ActionRowBuilder');
|
||||
const { RangeError } = require('../errors');
|
||||
const { RangeError, ErrorCodes } = require('../errors');
|
||||
const DataResolver = require('../util/DataResolver');
|
||||
const MessageFlagsBitField = require('../util/MessageFlagsBitField');
|
||||
const { basename, cloneObject, verifyString } = require('../util/Util');
|
||||
@@ -105,7 +105,7 @@ class MessagePayload {
|
||||
if (this.options.content === null) {
|
||||
content = '';
|
||||
} else if (typeof this.options.content !== 'undefined') {
|
||||
content = verifyString(this.options.content, RangeError, 'MESSAGE_CONTENT_TYPE', true);
|
||||
content = verifyString(this.options.content, RangeError, ErrorCodes.MessageContentType, true);
|
||||
}
|
||||
|
||||
return content;
|
||||
@@ -128,7 +128,7 @@ class MessagePayload {
|
||||
nonce = this.options.nonce;
|
||||
// eslint-disable-next-line max-len
|
||||
if (typeof nonce === 'number' ? !Number.isInteger(nonce) : typeof nonce !== 'string') {
|
||||
throw new RangeError('MESSAGE_NONCE_TYPE');
|
||||
throw new RangeError(ErrorCodes.MessageNonceType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { ComponentType } = require('discord-api-types/v10');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Represents the serialized fields from a modal submit interaction
|
||||
@@ -33,10 +33,10 @@ class ModalSubmitFields {
|
||||
*/
|
||||
getField(customId, type) {
|
||||
const field = this.fields.get(customId);
|
||||
if (!field) throw new TypeError('MODAL_SUBMIT_INTERACTION_FIELD_NOT_FOUND', customId);
|
||||
if (!field) throw new TypeError(ErrorCodes.ModalSubmitInteractionFieldNotFound, customId);
|
||||
|
||||
if (type !== undefined && type !== field.type) {
|
||||
throw new TypeError('MODAL_SUBMIT_INTERACTION_FIELD_TYPE', customId, field.type, type);
|
||||
throw new TypeError(ErrorCodes.ModalSubmitInteractionFieldType, customId, field.type, type);
|
||||
}
|
||||
|
||||
return field;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const BaseGuildTextChannel = require('./BaseGuildTextChannel');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Represents a guild news channel on Discord.
|
||||
@@ -23,7 +23,7 @@ class NewsChannel extends BaseGuildTextChannel {
|
||||
*/
|
||||
async addFollower(channel, reason) {
|
||||
const channelId = this.guild.channels.resolveId(channel);
|
||||
if (!channelId) throw new Error('GUILD_CHANNEL_RESOLVE');
|
||||
if (!channelId) throw new Error(ErrorCodes.GuildChannelResolve);
|
||||
await this.client.rest.post(Routes.channelFollowers(this.id), { body: { webhook_channel_id: channelId }, reason });
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { Channel } = require('./Channel');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Represents a Partial Group DM Channel on Discord.
|
||||
@@ -46,11 +46,11 @@ class PartialGroupDMChannel extends Channel {
|
||||
}
|
||||
|
||||
delete() {
|
||||
return Promise.reject(new Error('DELETE_GROUP_DM_CHANNEL'));
|
||||
return Promise.reject(new Error(ErrorCodes.DeleteGroupDMChannel));
|
||||
}
|
||||
|
||||
fetch() {
|
||||
return Promise.reject(new Error('FETCH_GROUP_DM_CHANNEL'));
|
||||
return Promise.reject(new Error(ErrorCodes.FetchGroupDMChannel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { OverwriteType } = require('discord-api-types/v10');
|
||||
const Base = require('./Base');
|
||||
const { Role } = require('./Role');
|
||||
const { TypeError } = require('../errors');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
|
||||
/**
|
||||
@@ -181,7 +181,7 @@ class PermissionOverwrites extends Base {
|
||||
}
|
||||
|
||||
const userOrRole = guild.roles.resolve(overwrite.id) ?? guild.client.users.resolve(overwrite.id);
|
||||
if (!userOrRole) throw new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role');
|
||||
if (!userOrRole) throw new TypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role');
|
||||
const type = userOrRole instanceof Role ? OverwriteType.Role : OverwriteType.Member;
|
||||
|
||||
return {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { PermissionFlagsBits } = require('discord-api-types/v10');
|
||||
const Base = require('./Base');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
|
||||
/**
|
||||
@@ -228,7 +228,7 @@ class Role extends Base {
|
||||
*/
|
||||
permissionsIn(channel, checkAdmin = true) {
|
||||
channel = this.guild.channels.resolve(channel);
|
||||
if (!channel) throw new Error('GUILD_CHANNEL_RESOLVE');
|
||||
if (!channel) throw new Error(ErrorCodes.GuildChannelResolve);
|
||||
return channel.rolePermissions(this, checkAdmin);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { Routes, StickerFormatType } = require('discord-api-types/v10');
|
||||
const Base = require('./Base');
|
||||
const { ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Represents a Sticker.
|
||||
@@ -190,7 +191,7 @@ class Sticker extends Base {
|
||||
*/
|
||||
async fetchUser() {
|
||||
if (this.partial) await this.fetch();
|
||||
if (!this.guildId) throw new Error('NOT_GUILD_STICKER');
|
||||
if (!this.guildId) throw new Error(ErrorCodes.NotGuildSticker);
|
||||
return this.guild.stickers.fetchUser(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { ChannelType, PermissionFlagsBits, Routes } = require('discord-api-types/v10');
|
||||
const { Channel } = require('./Channel');
|
||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||
const { RangeError } = require('../errors');
|
||||
const { RangeError, ErrorCodes } = require('../errors');
|
||||
const MessageManager = require('../managers/MessageManager');
|
||||
const ThreadMemberManager = require('../managers/ThreadMemberManager');
|
||||
|
||||
@@ -369,7 +369,7 @@ class ThreadChannel extends Channel {
|
||||
*/
|
||||
setInvitable(invitable = true, reason) {
|
||||
if (this.type !== ChannelType.GuildPrivateThread) {
|
||||
return Promise.reject(new RangeError('THREAD_INVITABLE_TYPE', this.type));
|
||||
return Promise.reject(new RangeError(ErrorCodes.ThreadInvitableType, this.type));
|
||||
}
|
||||
return this.edit({ invitable, reason });
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const { ChannelType, Routes } = require('discord-api-types/v10');
|
||||
const Base = require('./Base');
|
||||
const { Error, TypeError } = require('../errors');
|
||||
const { Error, TypeError, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Represents the voice state for a Guild Member.
|
||||
@@ -219,20 +219,20 @@ class VoiceState extends Base {
|
||||
* @returns {Promise<VoiceState>}
|
||||
*/
|
||||
async edit(data) {
|
||||
if (this.channel?.type !== ChannelType.GuildStageVoice) throw new Error('VOICE_NOT_STAGE_CHANNEL');
|
||||
if (this.channel?.type !== ChannelType.GuildStageVoice) throw new Error(ErrorCodes.VoiceNotStageChannel);
|
||||
|
||||
const target = this.client.user.id === this.id ? '@me' : this.id;
|
||||
|
||||
if (target !== '@me' && typeof data.requestToSpeak !== 'undefined') {
|
||||
throw new Error('VOICE_STATE_NOT_OWN');
|
||||
throw new Error(ErrorCodes.VoiceStateNotOwn);
|
||||
}
|
||||
|
||||
if (!['boolean', 'undefined'].includes(typeof data.requestToSpeak)) {
|
||||
throw new TypeError('VOICE_STATE_INVALID_TYPE', 'requestToSpeak');
|
||||
throw new TypeError(ErrorCodes.VoiceStateInvalidType, 'requestToSpeak');
|
||||
}
|
||||
|
||||
if (!['boolean', 'undefined'].includes(typeof data.suppressed)) {
|
||||
throw new TypeError('VOICE_STATE_INVALID_TYPE', 'suppressed');
|
||||
throw new TypeError(ErrorCodes.VoiceStateInvalidType, 'suppressed');
|
||||
}
|
||||
|
||||
await this.client.rest.patch(Routes.guildVoiceState(this.guild.id, target), {
|
||||
|
||||
@@ -4,7 +4,7 @@ const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { Routes, WebhookType } = require('discord-api-types/v10');
|
||||
const MessagePayload = require('./MessagePayload');
|
||||
const { Error } = require('../errors');
|
||||
const { Error, ErrorCodes } = require('../errors');
|
||||
const DataResolver = require('../util/DataResolver');
|
||||
const { lazy } = require('../util/Util');
|
||||
|
||||
@@ -194,7 +194,7 @@ class Webhook {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async send(options) {
|
||||
if (!this.token) throw new Error('WEBHOOK_TOKEN_UNAVAILABLE');
|
||||
if (!this.token) throw new Error(ErrorCodes.WebhookTokenUnavailable);
|
||||
|
||||
let messagePayload;
|
||||
|
||||
@@ -235,7 +235,7 @@ class Webhook {
|
||||
* @see {@link https://api.slack.com/messaging/webhooks}
|
||||
*/
|
||||
async sendSlackMessage(body) {
|
||||
if (!this.token) throw new Error('WEBHOOK_TOKEN_UNAVAILABLE');
|
||||
if (!this.token) throw new Error(ErrorCodes.WebhookTokenUnavailable);
|
||||
|
||||
const data = await this.client.rest.post(Routes.webhookPlatform(this.id, this.token, 'slack'), {
|
||||
query: makeURLSearchParams({ wait: true }),
|
||||
@@ -291,7 +291,7 @@ class Webhook {
|
||||
* @returns {Promise<APIMessage>} Returns the message sent by this webhook
|
||||
*/
|
||||
async fetchMessage(message, { threadId } = {}) {
|
||||
if (!this.token) throw new Error('WEBHOOK_TOKEN_UNAVAILABLE');
|
||||
if (!this.token) throw new Error(ErrorCodes.WebhookTokenUnavailable);
|
||||
|
||||
const data = await this.client.rest.get(Routes.webhookMessage(this.id, this.token, message), {
|
||||
query: threadId ? makeURLSearchParams({ thread_id: threadId }) : undefined,
|
||||
@@ -312,7 +312,7 @@ class Webhook {
|
||||
* @returns {Promise<APIMessage>} Returns the message edited by this webhook
|
||||
*/
|
||||
async editMessage(message, options) {
|
||||
if (!this.token) throw new Error('WEBHOOK_TOKEN_UNAVAILABLE');
|
||||
if (!this.token) throw new Error(ErrorCodes.WebhookTokenUnavailable);
|
||||
|
||||
let messagePayload;
|
||||
|
||||
@@ -363,7 +363,7 @@ class Webhook {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async deleteMessage(message, threadId) {
|
||||
if (!this.token) throw new Error('WEBHOOK_TOKEN_UNAVAILABLE');
|
||||
if (!this.token) throw new Error(ErrorCodes.WebhookTokenUnavailable);
|
||||
|
||||
await this.client.rest.delete(
|
||||
Routes.webhookMessage(this.id, this.token, typeof message === 'string' ? message : message.id),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const EventEmitter = require('node:events');
|
||||
const { setTimeout, clearTimeout } = require('node:timers');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { TypeError } = require('../../errors');
|
||||
const { TypeError, ErrorCodes } = require('../../errors');
|
||||
const { flatten } = require('../../util/Util');
|
||||
|
||||
/**
|
||||
@@ -86,7 +86,7 @@ class Collector extends EventEmitter {
|
||||
this._endReason = null;
|
||||
|
||||
if (typeof this.filter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'options.filter', 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'options.filter', 'function');
|
||||
}
|
||||
|
||||
this.handleCollect = this.handleCollect.bind(this);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const { isJSONEncodable } = require('@discordjs/builders');
|
||||
const { InteractionResponseType, MessageFlags, Routes, InteractionType } = require('discord-api-types/v10');
|
||||
const { Error } = require('../../errors');
|
||||
const { Error, ErrorCodes } = require('../../errors');
|
||||
const InteractionCollector = require('../InteractionCollector');
|
||||
const InteractionResponse = require('../InteractionResponse');
|
||||
const MessagePayload = require('../MessagePayload');
|
||||
@@ -63,7 +63,7 @@ class InteractionResponses {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async deferReply(options = {}) {
|
||||
if (this.deferred || this.replied) throw new Error('INTERACTION_ALREADY_REPLIED');
|
||||
if (this.deferred || this.replied) throw new Error(ErrorCodes.InteractionAlreadyReplied);
|
||||
this.ephemeral = options.ephemeral ?? false;
|
||||
await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
|
||||
body: {
|
||||
@@ -98,7 +98,7 @@ class InteractionResponses {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async reply(options) {
|
||||
if (this.deferred || this.replied) throw new Error('INTERACTION_ALREADY_REPLIED');
|
||||
if (this.deferred || this.replied) throw new Error(ErrorCodes.InteractionAlreadyReplied);
|
||||
this.ephemeral = options.ephemeral ?? false;
|
||||
|
||||
let messagePayload;
|
||||
@@ -146,7 +146,7 @@ class InteractionResponses {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async editReply(options) {
|
||||
if (!this.deferred && !this.replied) throw new Error('INTERACTION_NOT_REPLIED');
|
||||
if (!this.deferred && !this.replied) throw new Error(ErrorCodes.InteractionNotReplied);
|
||||
const message = await this.webhook.editMessage('@original', options);
|
||||
this.replied = true;
|
||||
return message;
|
||||
@@ -163,7 +163,7 @@ class InteractionResponses {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async deleteReply() {
|
||||
if (this.ephemeral) throw new Error('INTERACTION_EPHEMERAL_REPLIED');
|
||||
if (this.ephemeral) throw new Error(ErrorCodes.InteractionEphemeralReplied);
|
||||
await this.webhook.deleteMessage('@original');
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ class InteractionResponses {
|
||||
* @returns {Promise<Message|APIMessage>}
|
||||
*/
|
||||
followUp(options) {
|
||||
if (!this.deferred && !this.replied) return Promise.reject(new Error('INTERACTION_NOT_REPLIED'));
|
||||
if (!this.deferred && !this.replied) return Promise.reject(new Error(ErrorCodes.InteractionNotReplied));
|
||||
return this.webhook.send(options);
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ class InteractionResponses {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async deferUpdate(options = {}) {
|
||||
if (this.deferred || this.replied) throw new Error('INTERACTION_ALREADY_REPLIED');
|
||||
if (this.deferred || this.replied) throw new Error(ErrorCodes.InteractionAlreadyReplied);
|
||||
await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
|
||||
body: {
|
||||
type: InteractionResponseType.DeferredMessageUpdate,
|
||||
@@ -214,7 +214,7 @@ class InteractionResponses {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async update(options) {
|
||||
if (this.deferred || this.replied) throw new Error('INTERACTION_ALREADY_REPLIED');
|
||||
if (this.deferred || this.replied) throw new Error(ErrorCodes.InteractionAlreadyReplied);
|
||||
|
||||
let messagePayload;
|
||||
if (options instanceof MessagePayload) messagePayload = options;
|
||||
@@ -240,7 +240,7 @@ class InteractionResponses {
|
||||
* @param {APIModal|ModalData|Modal} modal The modal to show
|
||||
*/
|
||||
async showModal(modal) {
|
||||
if (this.deferred || this.replied) throw new Error('INTERACTION_ALREADY_REPLIED');
|
||||
if (this.deferred || this.replied) throw new Error(ErrorCodes.InteractionAlreadyReplied);
|
||||
await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
|
||||
body: {
|
||||
type: InteractionResponseType.Modal,
|
||||
@@ -270,14 +270,14 @@ class InteractionResponses {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
awaitModalSubmit(options) {
|
||||
if (typeof options.time !== 'number') throw new Error('INVALID_TYPE', 'time', 'number');
|
||||
if (typeof options.time !== 'number') throw new Error(ErrorCodes.InvalidType, 'time', 'number');
|
||||
const _options = { ...options, max: 1, interactionType: InteractionType.ModalSubmit };
|
||||
return new Promise((resolve, reject) => {
|
||||
const collector = new InteractionCollector(this.client, _options);
|
||||
collector.once('end', (interactions, reason) => {
|
||||
const interaction = interactions.first();
|
||||
if (interaction) resolve(interaction);
|
||||
else reject(new Error('INTERACTION_COLLECTOR_ERROR', reason));
|
||||
else reject(new Error(ErrorCodes.InteractionCollectorError, reason));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { InteractionType, Routes } = require('discord-api-types/v10');
|
||||
const { TypeError, Error } = require('../../errors');
|
||||
const { TypeError, Error, ErrorCodes } = require('../../errors');
|
||||
const InteractionCollector = require('../InteractionCollector');
|
||||
const MessageCollector = require('../MessageCollector');
|
||||
const MessagePayload = require('../MessagePayload');
|
||||
@@ -273,7 +273,7 @@ class TextBasedChannel {
|
||||
collector.once('end', (interactions, reason) => {
|
||||
const interaction = interactions.first();
|
||||
if (interaction) resolve(interaction);
|
||||
else reject(new Error('INTERACTION_COLLECTOR_ERROR', reason));
|
||||
else reject(new Error(ErrorCodes.InteractionCollectorError, reason));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -326,7 +326,7 @@ class TextBasedChannel {
|
||||
const msgs = await this.messages.fetch({ limit: messages });
|
||||
return this.bulkDelete(msgs, filterOld);
|
||||
}
|
||||
throw new TypeError('MESSAGE_BULK_DELETE_TYPE');
|
||||
throw new TypeError(ErrorCodes.MessageBulkDeleteType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { RangeError } = require('../errors');
|
||||
const { RangeError, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a bitfield.
|
||||
@@ -165,7 +165,7 @@ class BitField {
|
||||
if (typeof this.Flags[bit] !== 'undefined') return this.Flags[bit];
|
||||
if (!isNaN(bit)) return typeof DefaultBit === 'bigint' ? BigInt(bit) : Number(bit);
|
||||
}
|
||||
throw new RangeError('BITFIELD_INVALID', bit);
|
||||
throw new RangeError(ErrorCodes.BitFieldInvalid, bit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ const { Buffer } = require('node:buffer');
|
||||
const fs = require('node:fs/promises');
|
||||
const path = require('node:path');
|
||||
const { fetch } = require('undici');
|
||||
const { Error: DiscordError, TypeError } = require('../errors');
|
||||
const { Error: DiscordError, TypeError, ErrorCodes } = require('../errors');
|
||||
const Invite = require('../structures/Invite');
|
||||
|
||||
/**
|
||||
@@ -124,11 +124,11 @@ class DataResolver extends null {
|
||||
const file = path.resolve(resource);
|
||||
|
||||
const stats = await fs.stat(file);
|
||||
if (!stats.isFile()) throw new DiscordError('FILE_NOT_FOUND', file);
|
||||
if (!stats.isFile()) throw new DiscordError(ErrorCodes.FileNotFound, file);
|
||||
return fs.readFile(file);
|
||||
}
|
||||
|
||||
throw new TypeError('REQ_RESOURCE_TYPE');
|
||||
throw new TypeError(ErrorCodes.ReqResourceType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { TypeError } = require('../errors/DJSError.js');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* Options for defining the behavior of a LimitedCollection
|
||||
@@ -20,15 +20,15 @@ const { TypeError } = require('../errors/DJSError.js');
|
||||
class LimitedCollection extends Collection {
|
||||
constructor(options = {}, iterable) {
|
||||
if (typeof options !== 'object' || options === null) {
|
||||
throw new TypeError('INVALID_TYPE', 'options', 'object', true);
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'options', 'object', true);
|
||||
}
|
||||
const { maxSize = Infinity, keepOverLimit = null } = options;
|
||||
|
||||
if (typeof maxSize !== 'number') {
|
||||
throw new TypeError('INVALID_TYPE', 'maxSize', 'number');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'maxSize', 'number');
|
||||
}
|
||||
if (keepOverLimit !== null && typeof keepOverLimit !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'keepOverLimit', 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'keepOverLimit', 'function');
|
||||
}
|
||||
|
||||
super(iterable);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
const { setInterval, clearInterval } = require('node:timers');
|
||||
const { ThreadChannelTypes, SweeperKeys } = require('./Constants');
|
||||
const Events = require('./Events');
|
||||
const { TypeError } = require('../errors/DJSError.js');
|
||||
const { TypeError, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* @typedef {Function} GlobalSweepFilter
|
||||
@@ -131,7 +131,7 @@ class Sweepers {
|
||||
*/
|
||||
sweepMessages(filter) {
|
||||
if (typeof filter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'filter', 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'filter', 'function');
|
||||
}
|
||||
let channels = 0;
|
||||
let messages = 0;
|
||||
@@ -162,7 +162,7 @@ class Sweepers {
|
||||
*/
|
||||
sweepReactions(filter) {
|
||||
if (typeof filter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'filter', 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'filter', 'function');
|
||||
}
|
||||
let channels = 0;
|
||||
let messages = 0;
|
||||
@@ -210,7 +210,7 @@ class Sweepers {
|
||||
*/
|
||||
sweepThreadMembers(filter) {
|
||||
if (typeof filter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'filter', 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'filter', 'function');
|
||||
}
|
||||
|
||||
let threads = 0;
|
||||
@@ -240,7 +240,7 @@ class Sweepers {
|
||||
*/
|
||||
sweepThreads(filter) {
|
||||
if (typeof filter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'filter', 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'filter', 'function');
|
||||
}
|
||||
|
||||
let threads = 0;
|
||||
@@ -262,7 +262,7 @@ class Sweepers {
|
||||
*/
|
||||
sweepUsers(filter) {
|
||||
if (typeof filter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'filter', 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'filter', 'function');
|
||||
}
|
||||
|
||||
const users = this.client.users.cache.sweep(filter);
|
||||
@@ -313,13 +313,13 @@ class Sweepers {
|
||||
excludeFromSweep = () => false,
|
||||
} = {}) {
|
||||
if (typeof lifetime !== 'number') {
|
||||
throw new TypeError('INVALID_TYPE', 'lifetime', 'number');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'lifetime', 'number');
|
||||
}
|
||||
if (typeof getComparisonTimestamp !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'getComparisonTimestamp', 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'getComparisonTimestamp', 'function');
|
||||
}
|
||||
if (typeof excludeFromSweep !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'excludeFromSweep', 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'excludeFromSweep', 'function');
|
||||
}
|
||||
return () => {
|
||||
if (lifetime <= 0) return null;
|
||||
@@ -391,7 +391,7 @@ class Sweepers {
|
||||
*/
|
||||
_sweepGuildDirectProp(key, filter, { emit = true, outputName } = {}) {
|
||||
if (typeof filter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', 'filter', 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, 'filter', 'function');
|
||||
}
|
||||
|
||||
let guilds = 0;
|
||||
@@ -419,20 +419,20 @@ class Sweepers {
|
||||
_validateProperties(key) {
|
||||
const props = this.options[key];
|
||||
if (typeof props !== 'object') {
|
||||
throw new TypeError('INVALID_TYPE', `sweepers.${key}`, 'object', true);
|
||||
throw new TypeError(ErrorCodes.InvalidType, `sweepers.${key}`, 'object', true);
|
||||
}
|
||||
if (typeof props.interval !== 'number') {
|
||||
throw new TypeError('INVALID_TYPE', `sweepers.${key}.interval`, 'number');
|
||||
throw new TypeError(ErrorCodes.InvalidType, `sweepers.${key}.interval`, 'number');
|
||||
}
|
||||
// Invites, Messages, and Threads can be provided a lifetime parameter, which we use to generate the filter
|
||||
if (['invites', 'messages', 'threads'].includes(key) && !('filter' in props)) {
|
||||
if (typeof props.lifetime !== 'number') {
|
||||
throw new TypeError('INVALID_TYPE', `sweepers.${key}.lifetime`, 'number');
|
||||
throw new TypeError(ErrorCodes.InvalidType, `sweepers.${key}.lifetime`, 'number');
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (typeof props.filter !== 'function') {
|
||||
throw new TypeError('INVALID_TYPE', `sweepers.${key}.filter`, 'function');
|
||||
throw new TypeError(ErrorCodes.InvalidType, `sweepers.${key}.filter`, 'function');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,7 +448,7 @@ class Sweepers {
|
||||
this.intervals[intervalKey] = setInterval(() => {
|
||||
const sweepFn = opts.filter();
|
||||
if (sweepFn === null) return;
|
||||
if (typeof sweepFn !== 'function') throw new TypeError('SWEEP_FILTER_RETURN');
|
||||
if (typeof sweepFn !== 'function') throw new TypeError(ErrorCodes.SweepFilterReturn);
|
||||
this[sweepKey](sweepFn);
|
||||
}, opts.interval * 1_000).unref();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ const { Collection } = require('@discordjs/collection');
|
||||
const { ChannelType, RouteBases, Routes } = require('discord-api-types/v10');
|
||||
const { fetch } = require('undici');
|
||||
const Colors = require('./Colors');
|
||||
const { Error: DiscordError, RangeError, TypeError } = require('../errors');
|
||||
const { Error: DiscordError, RangeError, TypeError, ErrorCodes } = require('../errors');
|
||||
const isObject = d => typeof d === 'object' && d !== null;
|
||||
|
||||
/**
|
||||
@@ -223,13 +223,13 @@ function escapeSpoiler(text) {
|
||||
* @returns {Promise<number>} The recommended number of shards
|
||||
*/
|
||||
async function fetchRecommendedShards(token, { guildsPerShard = 1_000, multipleOf = 1 } = {}) {
|
||||
if (!token) throw new DiscordError('TOKEN_MISSING');
|
||||
if (!token) throw new DiscordError(ErrorCodes.TokenMissing);
|
||||
const response = await fetch(RouteBases.api + Routes.gatewayBot(), {
|
||||
method: 'GET',
|
||||
headers: { Authorization: `Bot ${token.replace(/^Bot\s*/i, '')}` },
|
||||
});
|
||||
if (!response.ok) {
|
||||
if (response.status === 401) throw new DiscordError('TOKEN_INVALID');
|
||||
if (response.status === 401) throw new DiscordError(ErrorCodes.TokenInvalid);
|
||||
throw response;
|
||||
}
|
||||
const { shards } = await response.json();
|
||||
@@ -423,8 +423,8 @@ function resolveColor(color) {
|
||||
color = (color[0] << 16) + (color[1] << 8) + color[2];
|
||||
}
|
||||
|
||||
if (color < 0 || color > 0xffffff) throw new RangeError('COLOR_RANGE');
|
||||
else if (Number.isNaN(color)) throw new TypeError('COLOR_CONVERT');
|
||||
if (color < 0 || color > 0xffffff) throw new RangeError(ErrorCodes.ColorRange);
|
||||
else if (Number.isNaN(color)) throw new TypeError(ErrorCodes.ColorConvert);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
163
packages/discord.js/typings/index.d.ts
vendored
163
packages/discord.js/typings/index.d.ts
vendored
@@ -2995,6 +2995,169 @@ export const version: string;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Errors
|
||||
export enum DiscordjsErrorCodes {
|
||||
ClientInvalidOption,
|
||||
ClientInvalidProvidedShards,
|
||||
ClientMissingIntents,
|
||||
ClientNotReady,
|
||||
|
||||
TokenInvalid,
|
||||
TokenMissing,
|
||||
ApplicationCommandPermissionsTokenMissing,
|
||||
|
||||
WSCloseRequested,
|
||||
WSConnectionExists,
|
||||
WSNotOpen,
|
||||
ManagerDestroyed,
|
||||
|
||||
BitFieldInvalid,
|
||||
|
||||
ShardingInvalid,
|
||||
ShardingRequired,
|
||||
InvalidIntents,
|
||||
DisallowedIntents,
|
||||
ShardingNoShards,
|
||||
ShardingInProcess,
|
||||
ShardingInvalidEvalBroadcast,
|
||||
ShardingShardNotFound,
|
||||
ShardingAlreadySpawned,
|
||||
ShardingProcessExists,
|
||||
ShardingWorkerExists,
|
||||
ShardingReadyTimeout,
|
||||
ShardingReadyDisconnected,
|
||||
ShardingReadyDied,
|
||||
ShardingNoChildExists,
|
||||
ShardingShardMiscalculation,
|
||||
|
||||
ColorRange,
|
||||
ColorConvert,
|
||||
|
||||
InviteOptionsMissingChannel,
|
||||
|
||||
ButtonLabel,
|
||||
ButtonURL,
|
||||
ButtonCustomId,
|
||||
|
||||
SelectMenuCustomId,
|
||||
SelectMenuPlaceholder,
|
||||
SelectOptionLabel,
|
||||
SelectOptionValue,
|
||||
SelectOptionDescription,
|
||||
|
||||
InteractionCollectorError,
|
||||
|
||||
FileNotFound,
|
||||
|
||||
UserBannerNotFetched,
|
||||
UserNoDMChannel,
|
||||
|
||||
VoiceNotStageChannel,
|
||||
|
||||
VoiceStateNotOwn,
|
||||
VoiceStateInvalidType,
|
||||
|
||||
ReqResourceType,
|
||||
|
||||
ImageFormat,
|
||||
ImageSize,
|
||||
|
||||
MessageBulkDeleteType,
|
||||
MessageNonceType,
|
||||
MessageContentType,
|
||||
|
||||
SplitMaxLen,
|
||||
|
||||
BanResolveId,
|
||||
FetchBanResolveId,
|
||||
|
||||
PruneDaysType,
|
||||
|
||||
GuildChannelResolve,
|
||||
GuildVoiceChannelResolve,
|
||||
GuildChannelOrphan,
|
||||
GuildChannelUnowned,
|
||||
GuildOwned,
|
||||
GuildMembersTimeout,
|
||||
GuildUncachedMe,
|
||||
ChannelNotCached,
|
||||
StageChannelResolve,
|
||||
GuildScheduledEventResolve,
|
||||
FetchOwnerId,
|
||||
|
||||
InvalidType,
|
||||
InvalidElement,
|
||||
|
||||
MessageThreadParent,
|
||||
MessageExistingThread,
|
||||
ThreadInvitableType,
|
||||
|
||||
WebhookMessage,
|
||||
WebhookTokenUnavailable,
|
||||
WebhookURLInvalid,
|
||||
WebhookApplication,
|
||||
MessageReferenceMissing,
|
||||
|
||||
EmojiType,
|
||||
EmojiManaged,
|
||||
MissingManageEmojisAndStickersPermission,
|
||||
NotGuildSticker,
|
||||
|
||||
ReactionResolveUser,
|
||||
|
||||
VanityURL,
|
||||
|
||||
InviteResolveCode,
|
||||
|
||||
InviteNotFound,
|
||||
|
||||
DeleteGroupDMChannel,
|
||||
FetchGroupDMChannel,
|
||||
|
||||
MemberFetchNonceLength,
|
||||
|
||||
GlobalCommandPermissions,
|
||||
GuildUncachedEntityResolve,
|
||||
|
||||
InteractionAlreadyReplied,
|
||||
InteractionNotReplied,
|
||||
InteractionEphemeralReplied,
|
||||
|
||||
CommandInteractionOptionNotFound,
|
||||
CommandInteractionOptionType,
|
||||
CommandInteractionOptionEmpty,
|
||||
CommandInteractionOptionNoSubcommand,
|
||||
CommandInteractionOptionNoSubcommandGroup,
|
||||
AutocompleteInteractionOptionNoFocusedOption,
|
||||
|
||||
ModalSubmitInteractionFieldNotFound,
|
||||
ModalSubmitInteractionFieldType,
|
||||
|
||||
InvalidMissingScopes,
|
||||
|
||||
NotImplemented,
|
||||
|
||||
SweepFilterReturn,
|
||||
}
|
||||
|
||||
export interface DiscordjsErrorFields<Name extends string> {
|
||||
readonly name: `${Name} [${keyof typeof DiscordjsErrorCodes}]`;
|
||||
get code(): keyof typeof DiscordjsErrorCodes;
|
||||
}
|
||||
|
||||
export function DiscordjsErrorMixin<T, N extends string>(
|
||||
Base: Constructable<T>,
|
||||
name: N,
|
||||
): Constructable<T & DiscordjsErrorFields<N>>;
|
||||
|
||||
export class DiscordjsError extends DiscordjsErrorMixin(Error, 'Error') {}
|
||||
|
||||
export class DiscordjsTypeError extends DiscordjsErrorMixin(TypeError, 'TypeError') {}
|
||||
|
||||
export class DiscordjsRangeError extends DiscordjsErrorMixin(RangeError, 'RangeError') {}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Managers
|
||||
|
||||
export abstract class BaseManager {
|
||||
|
||||
Reference in New Issue
Block a user