mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat(core): handle request all guild members rate limit (#11251)
* feat(core): handle request all guild members rate limit BREAKING CHANGE: `Gateway` now requires `off` `once` methods * fix: weird import update * refactor: error class * refactor: error class again * refactor: requested changes * chore: fix dep * fix: suggested changes --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
37a38883d7
commit
d3d6777ef8
@@ -1,6 +1,6 @@
|
||||
import { clearTimeout, setTimeout } from 'node:timers';
|
||||
import type { REST } from '@discordjs/rest';
|
||||
import { calculateShardId } from '@discordjs/util';
|
||||
import { calculateShardId, GatewayRateLimitError } from '@discordjs/util';
|
||||
import { WebSocketShardEvents } from '@discordjs/ws';
|
||||
import { DiscordSnowflake } from '@sapphire/snowflake';
|
||||
import { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';
|
||||
@@ -61,6 +61,7 @@ import {
|
||||
type GatewayMessageUpdateDispatchData,
|
||||
type GatewayPresenceUpdateData,
|
||||
type GatewayPresenceUpdateDispatchData,
|
||||
type GatewayRateLimitedDispatchData,
|
||||
type GatewayReadyDispatchData,
|
||||
type GatewayRequestGuildMembersData,
|
||||
type GatewayStageInstanceCreateDispatchData,
|
||||
@@ -164,6 +165,7 @@ export interface MappedEvents {
|
||||
[GatewayDispatchEvents.MessageReactionRemoveEmoji]: [ToEventProps<GatewayMessageReactionRemoveEmojiDispatchData>];
|
||||
[GatewayDispatchEvents.MessageUpdate]: [ToEventProps<GatewayMessageUpdateDispatchData>];
|
||||
[GatewayDispatchEvents.PresenceUpdate]: [ToEventProps<GatewayPresenceUpdateDispatchData>];
|
||||
[GatewayDispatchEvents.RateLimited]: [ToEventProps<GatewayRateLimitedDispatchData>];
|
||||
[GatewayDispatchEvents.Ready]: [ToEventProps<GatewayReadyDispatchData>];
|
||||
[GatewayDispatchEvents.Resumed]: [ToEventProps<never>];
|
||||
[GatewayDispatchEvents.StageInstanceCreate]: [ToEventProps<GatewayStageInstanceCreateDispatchData>];
|
||||
@@ -244,6 +246,22 @@ export class Client extends AsyncEventEmitter<MappedEvents> {
|
||||
|
||||
let timer: NodeJS.Timeout | undefined = createTimer(controller, timeout);
|
||||
|
||||
const onRatelimit = ({ data }: ToEventProps<GatewayRateLimitedDispatchData>) => {
|
||||
// We could verify meta.guild_id === options.guild_id as well, but really, the nonce check is enough
|
||||
if (data.meta.nonce === nonce) {
|
||||
controller.abort(new GatewayRateLimitError(data, options));
|
||||
}
|
||||
};
|
||||
|
||||
const cleanup = () => {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
this.off(GatewayDispatchEvents.RateLimited, onRatelimit);
|
||||
};
|
||||
|
||||
this.on(GatewayDispatchEvents.RateLimited, onRatelimit);
|
||||
await this.gateway.send(shardId, {
|
||||
op: GatewayOpcodes.RequestGuildMembers,
|
||||
// eslint-disable-next-line id-length
|
||||
@@ -275,18 +293,21 @@ export class Client extends AsyncEventEmitter<MappedEvents> {
|
||||
|
||||
if (data.chunk_index >= data.chunk_count - 1) break;
|
||||
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
timer = createTimer(controller, timeout);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.name === 'AbortError') {
|
||||
if (error.cause instanceof GatewayRateLimitError) {
|
||||
throw error.cause;
|
||||
}
|
||||
|
||||
throw new Error('Request timed out');
|
||||
}
|
||||
|
||||
throw error;
|
||||
} finally {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ export * from './util/index.js';
|
||||
|
||||
export * from 'discord-api-types/v10';
|
||||
|
||||
export { GatewayRateLimitError } from '@discordjs/util';
|
||||
|
||||
/**
|
||||
* The {@link https://github.com/discordjs/discord.js/blob/main/packages/core#readme | @discordjs/core} version
|
||||
* that you are currently using.
|
||||
|
||||
Reference in New Issue
Block a user