refactor: use throw instead of Promise.reject

#10712 djs
This commit is contained in:
Elysia
2025-02-14 23:47:07 +07:00
parent 3afa12574a
commit c1c0a62a0e
17 changed files with 63 additions and 64 deletions

View File

@@ -114,7 +114,7 @@
"no-void": "error", "no-void": "error",
// "no-warning-comments": "warn", // "no-warning-comments": "warn",
"prefer-promise-reject-errors": "error", "prefer-promise-reject-errors": "error",
"require-await": "warn", "require-await": "off",
"wrap-iife": "error", "wrap-iife": "error",
"yoda": "error", "yoda": "error",
"no-label-var": "error", "no-label-var": "error",

View File

@@ -760,15 +760,15 @@ class VoiceConnection extends EventEmitter {
* @param {UserResolvable} user Discord user * @param {UserResolvable} user Discord user
* @returns {Promise<StreamConnectionReadonly>} * @returns {Promise<StreamConnectionReadonly>}
*/ */
joinStreamConnection(user) { async joinStreamConnection(user) {
const userId = this.client.users.resolveId(user); const userId = this.client.users.resolveId(user);
// Check if user is streaming // Check if user is streaming
if (!userId) { if (!userId) {
return Promise.reject(new Error('VOICE_USER_MISSING')); throw new Error('VOICE_USER_MISSING');
} }
const voiceState = this.channel.guild?.voiceStates.cache.get(userId) || this.client.voiceStates.cache.get(userId); const voiceState = this.channel.guild?.voiceStates.cache.get(userId) || this.client.voiceStates.cache.get(userId);
if (!voiceState || !voiceState.streaming) { if (!voiceState || !voiceState.streaming) {
return Promise.reject(new Error('VOICE_USER_NOT_STREAMING')); throw new Error('VOICE_USER_NOT_STREAMING');
} }
// eslint-disable-next-line consistent-return // eslint-disable-next-line consistent-return
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

View File

@@ -104,12 +104,8 @@ class VoiceWebSocket extends EventEmitter {
* @param {Object} packet The packet to send * @param {Object} packet The packet to send
* @returns {Promise<string>} * @returns {Promise<string>}
*/ */
sendPacket(packet) { async sendPacket(packet) {
try {
packet = JSON.stringify(packet); packet = JSON.stringify(packet);
} catch (error) {
return Promise.reject(error);
}
return this.send(packet); return this.send(packet);
} }

View File

@@ -95,14 +95,14 @@ class GuildBanManager extends CachedManager {
* .then(console.log) * .then(console.log)
* .catch(console.error); * .catch(console.error);
*/ */
fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(); if (!options) return this._fetchMany();
const { user, cache, force, limit, before, after } = options; const { user, cache, force, limit, before, after } = options;
const resolvedUser = this.client.users.resolveId(user ?? options); const resolvedUser = this.client.users.resolveId(user ?? options);
if (resolvedUser) return this._fetchSingle({ user: resolvedUser, cache, force }); if (resolvedUser) return this._fetchSingle({ user: resolvedUser, cache, force });
if (!before && !after && !limit && typeof cache === 'undefined') { if (!before && !after && !limit && typeof cache === 'undefined') {
return Promise.reject(new Error('FETCH_BAN_RESOLVE_ID')); throw new Error('FETCH_BAN_RESOLVE_ID');
} }
return this._fetchMany(options); return this._fetchMany(options);

View File

@@ -39,14 +39,14 @@ class GuildEmojiRoleManager extends DataManager {
* @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to add * @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to add
* @returns {Promise<GuildEmoji>} * @returns {Promise<GuildEmoji>}
*/ */
add(roleOrRoles) { async add(roleOrRoles) {
if (!Array.isArray(roleOrRoles) && !(roleOrRoles instanceof Collection)) roleOrRoles = [roleOrRoles]; if (!Array.isArray(roleOrRoles) && !(roleOrRoles instanceof Collection)) roleOrRoles = [roleOrRoles];
const resolvedRoles = []; const resolvedRoles = [];
for (const role of roleOrRoles.values()) { for (const role of roleOrRoles.values()) {
const resolvedRole = this.guild.roles.resolveId(role); const resolvedRole = this.guild.roles.resolveId(role);
if (!resolvedRole) { if (!resolvedRole) {
return Promise.reject(new TypeError('INVALID_ELEMENT', 'Array or Collection', 'roles', role)); throw new TypeError('INVALID_ELEMENT', 'Array or Collection', 'roles', role);
} }
resolvedRoles.push(resolvedRole); resolvedRoles.push(resolvedRole);
} }
@@ -60,14 +60,14 @@ class GuildEmojiRoleManager extends DataManager {
* @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to remove * @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to remove
* @returns {Promise<GuildEmoji>} * @returns {Promise<GuildEmoji>}
*/ */
remove(roleOrRoles) { async remove(roleOrRoles) {
if (!Array.isArray(roleOrRoles) && !(roleOrRoles instanceof Collection)) roleOrRoles = [roleOrRoles]; if (!Array.isArray(roleOrRoles) && !(roleOrRoles instanceof Collection)) roleOrRoles = [roleOrRoles];
const resolvedRoleIds = []; const resolvedRoleIds = [];
for (const role of roleOrRoles.values()) { for (const role of roleOrRoles.values()) {
const roleId = this.guild.roles.resolveId(role); const roleId = this.guild.roles.resolveId(role);
if (!roleId) { if (!roleId) {
return Promise.reject(new TypeError('INVALID_ELEMENT', 'Array or Collection', 'roles', role)); throw new TypeError('INVALID_ELEMENT', 'Array or Collection', 'roles', role);
} }
resolvedRoleIds.push(roleId); resolvedRoleIds.push(roleId);
} }

View File

@@ -119,22 +119,22 @@ class GuildInviteManager extends CachedManager {
* .then(console.log) * .then(console.log)
* .catch(console.error); * .catch(console.error);
*/ */
fetch(options) { async fetch(options) {
if (!options) return this._fetchMany(); if (!options) return this._fetchMany();
if (typeof options === 'string') { if (typeof options === 'string') {
const code = DataResolver.resolveInviteCode(options); const code = DataResolver.resolveInviteCode(options);
if (!code) return Promise.reject(new Error('INVITE_RESOLVE_CODE')); if (!code) throw new Error('INVITE_RESOLVE_CODE');
return this._fetchSingle({ code, cache: true }); return this._fetchSingle({ code, cache: true });
} }
if (!options.code) { if (!options.code) {
if (options.channelId) { if (options.channelId) {
const id = this.guild.channels.resolveId(options.channelId); const id = this.guild.channels.resolveId(options.channelId);
if (!id) return Promise.reject(new Error('GUILD_CHANNEL_RESOLVE')); if (!id) throw new Error('GUILD_CHANNEL_RESOLVE');
return this._fetchChannelMany(id, options.cache); return this._fetchChannelMany(id, options.cache);
} }
if ('cache' in options) return this._fetchMany(options.cache); if ('cache' in options) return this._fetchMany(options.cache);
return Promise.reject(new Error('INVITE_RESOLVE_CODE')); throw new Error('INVITE_RESOLVE_CODE');
} }
return this._fetchSingle({ return this._fetchSingle({
...options, ...options,

View File

@@ -394,7 +394,7 @@ class GuildMemberManager extends CachedManager {
*/ */
async kick(user, reason) { async kick(user, reason) {
const id = this.client.users.resolveId(user); const id = this.client.users.resolveId(user);
if (!id) return Promise.reject(new TypeError('INVALID_TYPE', 'user', 'UserResolvable')); if (!id) throw new TypeError('INVALID_TYPE', 'user', 'UserResolvable');
await this.client.api.guilds(this.guild.id).members(id).delete({ reason }); await this.client.api.guilds(this.guild.id).members(id).delete({ reason });

View File

@@ -62,11 +62,9 @@ class PermissionOverwriteManager extends CachedManager {
* }, * },
* ], 'Needed to change permissions'); * ], 'Needed to change permissions');
*/ */
set(overwrites, reason) { async set(overwrites, reason) {
if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) { if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) {
return Promise.reject( throw new TypeError('INVALID_TYPE', 'overwrites', 'Array or Collection of Permission Overwrites', true);
new TypeError('INVALID_TYPE', 'overwrites', 'Array or Collection of Permission Overwrites', true),
);
} }
return this.channel.edit({ permissionOverwrites: overwrites, reason }); return this.channel.edit({ permissionOverwrites: overwrites, reason });
} }

View File

@@ -237,9 +237,9 @@ class Shard extends EventEmitter {
* .then(count => console.log(`${count} guilds in shard ${shard.id}`)) * .then(count => console.log(`${count} guilds in shard ${shard.id}`))
* .catch(console.error); * .catch(console.error);
*/ */
fetchClientValue(prop) { async fetchClientValue(prop) {
// Shard is dead (maybe respawning), don't cache anything and error immediately // 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) throw new Error('SHARDING_NO_CHILD_EXISTS', this.id);
// Cached promise from previous call // Cached promise from previous call
if (this._fetches.has(prop)) return this._fetches.get(prop); if (this._fetches.has(prop)) return this._fetches.get(prop);
@@ -277,12 +277,12 @@ class Shard extends EventEmitter {
* @param {*} [context] The context for the eval * @param {*} [context] The context for the eval
* @returns {Promise<*>} Result of the script execution * @returns {Promise<*>} Result of the script execution
*/ */
eval(script, context) { async eval(script, context) {
// Stringify the script if it's a Function // Stringify the script if it's a Function
const _eval = typeof script === 'function' ? `(${script})(this, ${JSON.stringify(context)})` : script; const _eval = typeof script === 'function' ? `(${script})(this, ${JSON.stringify(context)})` : script;
// Shard is dead (maybe respawning), don't cache anything and error immediately // 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) throw new Error('SHARDING_NO_CHILD_EXISTS', this.id);
// Cached promise from previous call // Cached promise from previous call
if (this._evals.has(_eval)) return this._evals.get(_eval); if (this._evals.has(_eval)) return this._evals.get(_eval);

View File

@@ -248,8 +248,8 @@ class ShardingManager extends EventEmitter {
* @param {BroadcastEvalOptions} [options={}] The options for the broadcast * @param {BroadcastEvalOptions} [options={}] The options for the broadcast
* @returns {Promise<*|Array<*>>} Results of the script execution * @returns {Promise<*|Array<*>>} Results of the script execution
*/ */
broadcastEval(script, options = {}) { async broadcastEval(script, options = {}) {
if (typeof script !== 'function') return Promise.reject(new TypeError('SHARDING_INVALID_EVAL_BROADCAST')); if (typeof script !== 'function') throw new TypeError('SHARDING_INVALID_EVAL_BROADCAST');
return this._performOnShards('eval', [`(${script})(this, ${JSON.stringify(options.context)})`], options.shard); return this._performOnShards('eval', [`(${script})(this, ${JSON.stringify(options.context)})`], options.shard);
} }
@@ -275,15 +275,15 @@ class ShardingManager extends EventEmitter {
* @returns {Promise<*|Array<*>>} Results of the method execution * @returns {Promise<*|Array<*>>} Results of the method execution
* @private * @private
*/ */
_performOnShards(method, args, shard) { async _performOnShards(method, args, shard) {
if (this.shards.size === 0) return Promise.reject(new Error('SHARDING_NO_SHARDS')); if (this.shards.size === 0) throw new Error('SHARDING_NO_SHARDS');
if (typeof shard === 'number') { if (typeof shard === 'number') {
if (this.shards.has(shard)) return this.shards.get(shard)[method](...args); if (this.shards.has(shard)) return this.shards.get(shard)[method](...args);
return Promise.reject(new Error('SHARDING_SHARD_NOT_FOUND', shard)); throw new Error('SHARDING_SHARD_NOT_FOUND', shard);
} }
if (this.shards.size !== this.shardList.length) return Promise.reject(new Error('SHARDING_IN_PROCESS')); if (this.shards.size !== this.shardList.length) throw new Error('SHARDING_IN_PROCESS');
const promises = []; const promises = [];
for (const sh of this.shards.values()) promises.push(sh[method](...args)); for (const sh of this.shards.values()) promises.push(sh[method](...args));

View File

@@ -259,8 +259,8 @@ class GuildChannel extends Channel {
* Locks in the permission overwrites from the parent channel. * Locks in the permission overwrites from the parent channel.
* @returns {Promise<GuildChannel>} * @returns {Promise<GuildChannel>}
*/ */
lockPermissions() { async lockPermissions() {
if (!this.parent) return Promise.reject(new Error('GUILD_CHANNEL_ORPHAN')); if (!this.parent) throw new Error('GUILD_CHANNEL_ORPHAN');
const permissionOverwrites = this.parent.permissionOverwrites.cache.map(overwrite => overwrite.toJSON()); const permissionOverwrites = this.parent.permissionOverwrites.cache.map(overwrite => overwrite.toJSON());
return this.edit({ permissionOverwrites }); return this.edit({ permissionOverwrites });
} }

View File

@@ -738,8 +738,8 @@ class Message extends Base {
* .then(msg => console.log(`Updated the content of a message to ${msg.content}`)) * .then(msg => console.log(`Updated the content of a message to ${msg.content}`))
* .catch(console.error); * .catch(console.error);
*/ */
edit(options) { async edit(options) {
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED')); if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
return this.channel.messages.edit(this, options); return this.channel.messages.edit(this, options);
} }
@@ -754,8 +754,8 @@ class Message extends Base {
* .catch(console.error); * .catch(console.error);
* } * }
*/ */
crosspost() { async crosspost() {
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED')); if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
return this.channel.messages.crosspost(this.id); return this.channel.messages.crosspost(this.id);
} }
@@ -856,8 +856,8 @@ class Message extends Base {
* .then(() => console.log(`Replied to message "${message.content}"`)) * .then(() => console.log(`Replied to message "${message.content}"`))
* .catch(console.error); * .catch(console.error);
*/ */
reply(options) { async reply(options) {
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED')); if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
let data; let data;
if (options instanceof MessagePayload) { if (options instanceof MessagePayload) {
@@ -918,12 +918,12 @@ class Message extends Base {
* @param {StartThreadOptions} [options] Options for starting a thread on this message * @param {StartThreadOptions} [options] Options for starting a thread on this message
* @returns {Promise<ThreadChannel>} * @returns {Promise<ThreadChannel>}
*/ */
startThread(options = {}) { async startThread(options = {}) {
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED')); if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
if (!['GUILD_TEXT', 'GUILD_NEWS'].includes(this.channel.type)) { if (!['GUILD_TEXT', 'GUILD_NEWS'].includes(this.channel.type)) {
return Promise.reject(new Error('MESSAGE_THREAD_PARENT')); throw new Error('MESSAGE_THREAD_PARENT');
} }
if (this.hasThread) return Promise.reject(new Error('MESSAGE_EXISTING_THREAD')); if (this.hasThread) throw new Error('MESSAGE_EXISTING_THREAD');
return this.channel.threads.create({ ...options, startMessage: this }); return this.channel.threads.create({ ...options, startMessage: this });
} }
@@ -953,8 +953,8 @@ class Message extends Base {
* @param {boolean} [force=true] Whether to skip the cache check and request the API * @param {boolean} [force=true] Whether to skip the cache check and request the API
* @returns {Promise<Message>} * @returns {Promise<Message>}
*/ */
fetch(force = true) { async fetch(force = true) {
if (!this.channel) return Promise.reject(new Error('CHANNEL_NOT_CACHED')); if (!this.channel) throw new Error('CHANNEL_NOT_CACHED');
return this.channel.messages.fetch(this.id, { force }); return this.channel.messages.fetch(this.id, { force });
} }
@@ -962,9 +962,9 @@ class Message extends Base {
* Fetches the webhook used to create this message. * Fetches the webhook used to create this message.
* @returns {Promise<?Webhook>} * @returns {Promise<?Webhook>}
*/ */
fetchWebhook() { async fetchWebhook() {
if (!this.webhookId) return Promise.reject(new Error('WEBHOOK_MESSAGE')); if (!this.webhookId) throw new Error('WEBHOOK_MESSAGE');
if (this.webhookId === this.applicationId) return Promise.reject(new Error('WEBHOOK_APPLICATION')); if (this.webhookId === this.applicationId) throw new Error('WEBHOOK_APPLICATION');
return this.client.fetchWebhook(this.webhookId); return this.client.fetchWebhook(this.webhookId);
} }

View File

@@ -97,9 +97,9 @@ class Poll extends Base {
* Ends this poll. * Ends this poll.
* @returns {Promise<Message>} * @returns {Promise<Message>}
*/ */
end() { async end() {
if (Date.now() > this.expiresTimestamp) { if (Date.now() > this.expiresTimestamp) {
return Promise.reject(new Error('POLL_ALREADY_EXPIRED')); throw new Error('POLL_ALREADY_EXPIRED');
} }
return this.message.channel.messages.endPoll(this.message.id); return this.message.channel.messages.endPoll(this.message.id);
} }

View File

@@ -398,8 +398,8 @@ class ThreadChannel extends Channel {
* @param {string} [reason] Reason for changing invite * @param {string} [reason] Reason for changing invite
* @returns {Promise<ThreadChannel>} * @returns {Promise<ThreadChannel>}
*/ */
setInvitable(invitable = true, reason) { async setInvitable(invitable = true, reason) {
if (this.type !== 'GUILD_PRIVATE_THREAD') return Promise.reject(new RangeError('THREAD_INVITABLE_TYPE', this.type)); if (this.type !== 'GUILD_PRIVATE_THREAD') throw new RangeError('THREAD_INVITABLE_TYPE', this.type);
return this.edit({ invitable }, reason); return this.edit({ invitable }, reason);
} }

View File

@@ -172,8 +172,8 @@ class InteractionResponses {
* @param {string|MessagePayload|InteractionReplyOptions} options The options for the reply * @param {string|MessagePayload|InteractionReplyOptions} options The options for the reply
* @returns {Promise<Message|APIMessage>} * @returns {Promise<Message|APIMessage>}
*/ */
followUp(options) { async followUp(options) {
if (!this.deferred && !this.replied) return Promise.reject(new Error('INTERACTION_NOT_REPLIED')); if (!this.deferred && !this.replied) throw new Error('INTERACTION_NOT_REPLIED');
return this.webhook.send(options); return this.webhook.send(options);
} }

View File

@@ -160,7 +160,12 @@ class Options extends null {
return { return {
DMChannelVoiceStatusSync: 0, DMChannelVoiceStatusSync: 0,
captchaRetryLimit: 3, captchaRetryLimit: 3,
captchaSolver: () => Promise.reject(new Error('CAPTCHA_SOLVER_NOT_IMPLEMENTED')), captchaSolver: () => {
const err = new Error('CAPTCHA_SOLVER_NOT_IMPLEMENTED');
err.cause =
'You need to provide a captcha solver to use this feature\nEx: const sbClient = new Client({ captchaSolver: yourAsyncFunction })';
throw err;
},
TOTPKey: null, TOTPKey: null,
closeTimeout: 5_000, closeTimeout: 5_000,
waitGuildTimeout: 15_000, waitGuildTimeout: 15_000,

View File

@@ -930,7 +930,7 @@ class Util extends null {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Waiting for MsgCreate / ModalCreate // Waiting for MsgCreate / ModalCreate
let dataFromInteractionSuccess; let dataFromInteractionSuccess;
let dataFromNormal; let dataFromNormalEvent;
const handler = data => { const handler = data => {
// UnhandledPacket // UnhandledPacket
if (isHandlerDeferUpdate && data.d?.nonce == nonce && data.t == 'INTERACTION_SUCCESS') { if (isHandlerDeferUpdate && data.d?.nonce == nonce && data.t == 'INTERACTION_SUCCESS') {
@@ -946,19 +946,19 @@ class Util extends null {
client.removeListener(Events.INTERACTION_MODAL_CREATE, handler); client.removeListener(Events.INTERACTION_MODAL_CREATE, handler);
if (isHandlerDeferUpdate) client.removeListener(Events.UNHANDLED_PACKET, handler); if (isHandlerDeferUpdate) client.removeListener(Events.UNHANDLED_PACKET, handler);
client.decrementMaxListeners(); client.decrementMaxListeners();
dataFromNormal = data; dataFromNormalEvent = data;
resolve(data); resolve(data);
}; };
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
if (dataFromInteractionSuccess || dataFromNormal) { if (dataFromInteractionSuccess || dataFromNormalEvent) {
resolve(dataFromNormal || dataFromInteractionSuccess); resolve(dataFromNormalEvent || dataFromInteractionSuccess);
return; return;
} }
client.removeListener(Events.MESSAGE_CREATE, handler); client.removeListener(Events.MESSAGE_CREATE, handler);
client.removeListener(Events.INTERACTION_MODAL_CREATE, handler); client.removeListener(Events.INTERACTION_MODAL_CREATE, handler);
if (isHandlerDeferUpdate) client.removeListener(Events.UNHANDLED_PACKET, handler); if (isHandlerDeferUpdate) client.removeListener(Events.UNHANDLED_PACKET, handler);
client.decrementMaxListeners(); client.decrementMaxListeners();
reject(new Error('INTERACTION_FAILED')); reject(new DiscordError('INTERACTION_FAILED'));
}, timeoutMs).unref(); }, timeoutMs).unref();
client.incrementMaxListeners(); client.incrementMaxListeners();
client.on(Events.MESSAGE_CREATE, handler); client.on(Events.MESSAGE_CREATE, handler);