mirror of
https://github.com/discordjs/discord.js.git
synced 2024-08-21 04:14:46 +12:00
feat: expose Retry-After and sublimit timeouts in RatelimitData (#9864)
* feat: expose Retry-After and sublimit timeouts in RatelimitData * chore: better docs? * Apply suggestions from code review Co-authored-by: ckohen <chaikohen@gmail.com> --------- Co-authored-by: ckohen <chaikohen@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
parent
62e6573296
commit
81e7866903
4 changed files with 54 additions and 14 deletions
|
@ -17,7 +17,22 @@ export class RateLimitError extends Error implements RateLimitData {
|
|||
|
||||
public global: boolean;
|
||||
|
||||
public constructor({ timeToReset, limit, method, hash, url, route, majorParameter, global }: RateLimitData) {
|
||||
public retryAfter: number;
|
||||
|
||||
public sublimitTimeout: number;
|
||||
|
||||
public constructor({
|
||||
timeToReset,
|
||||
limit,
|
||||
method,
|
||||
hash,
|
||||
url,
|
||||
route,
|
||||
majorParameter,
|
||||
global,
|
||||
retryAfter,
|
||||
sublimitTimeout,
|
||||
}: RateLimitData) {
|
||||
super();
|
||||
this.timeToReset = timeToReset;
|
||||
this.limit = limit;
|
||||
|
@ -27,6 +42,8 @@ export class RateLimitError extends Error implements RateLimitData {
|
|||
this.route = route;
|
||||
this.majorParameter = majorParameter;
|
||||
this.global = global;
|
||||
this.retryAfter = retryAfter;
|
||||
this.sublimitTimeout = sublimitTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -102,16 +102,20 @@ export class BurstHandler implements IHandler {
|
|||
} else if (status === 429) {
|
||||
// Unexpected ratelimit
|
||||
const isGlobal = res.headers.has('X-RateLimit-Global');
|
||||
|
||||
await onRateLimit(this.manager, {
|
||||
timeToReset: retryAfter,
|
||||
limit: Number.POSITIVE_INFINITY,
|
||||
global: isGlobal,
|
||||
method,
|
||||
hash: this.hash,
|
||||
url,
|
||||
route: routeId.bucketRoute,
|
||||
majorParameter: this.majorParameter,
|
||||
global: isGlobal,
|
||||
hash: this.hash,
|
||||
limit: Number.POSITIVE_INFINITY,
|
||||
timeToReset: retryAfter,
|
||||
retryAfter,
|
||||
sublimitTimeout: 0,
|
||||
});
|
||||
|
||||
this.debug(
|
||||
[
|
||||
'Encountered unexpected 429 rate limit',
|
||||
|
|
|
@ -227,19 +227,23 @@ export class SequentialHandler implements IHandler {
|
|||
}
|
||||
|
||||
const rateLimitData: RateLimitData = {
|
||||
timeToReset: timeout,
|
||||
limit,
|
||||
global: isGlobal,
|
||||
method: options.method ?? 'get',
|
||||
hash: this.hash,
|
||||
url,
|
||||
route: routeId.bucketRoute,
|
||||
majorParameter: this.majorParameter,
|
||||
global: isGlobal,
|
||||
hash: this.hash,
|
||||
limit,
|
||||
timeToReset: timeout,
|
||||
retryAfter: timeout,
|
||||
sublimitTimeout: 0,
|
||||
};
|
||||
|
||||
// Let library users know they have hit a rate limit
|
||||
this.manager.emit(RESTEvents.RateLimited, rateLimitData);
|
||||
// Determine whether a RateLimitError should be thrown
|
||||
await onRateLimit(this.manager, rateLimitData);
|
||||
|
||||
// When not erroring, emit debug for what is happening
|
||||
if (isGlobal) {
|
||||
this.debug(`Global rate limit hit, blocking all requests for ${timeout}ms`);
|
||||
|
@ -345,15 +349,18 @@ export class SequentialHandler implements IHandler {
|
|||
}
|
||||
|
||||
await onRateLimit(this.manager, {
|
||||
timeToReset: timeout,
|
||||
limit,
|
||||
global: isGlobal,
|
||||
method,
|
||||
hash: this.hash,
|
||||
url,
|
||||
route: routeId.bucketRoute,
|
||||
majorParameter: this.majorParameter,
|
||||
global: isGlobal,
|
||||
hash: this.hash,
|
||||
limit,
|
||||
timeToReset: timeout,
|
||||
retryAfter,
|
||||
sublimitTimeout: sublimitTimeout ?? 0,
|
||||
});
|
||||
|
||||
this.debug(
|
||||
[
|
||||
'Encountered unexpected 429 rate limit',
|
||||
|
@ -368,6 +375,7 @@ export class SequentialHandler implements IHandler {
|
|||
` Sublimit : ${sublimitTimeout ? `${sublimitTimeout}ms` : 'None'}`,
|
||||
].join('\n'),
|
||||
);
|
||||
|
||||
// If caused by a sublimit, wait it out here so other requests on the route can be handled
|
||||
if (sublimitTimeout) {
|
||||
// Normally the sublimit queue will not exist, however, if a sublimit is hit while in the sublimit queue, it will
|
||||
|
|
|
@ -155,12 +155,23 @@ export interface RateLimitData {
|
|||
* The HTTP method being performed
|
||||
*/
|
||||
method: string;
|
||||
/**
|
||||
* The time, in milliseconds, that will need to pass before this specific request can be retried
|
||||
*/
|
||||
retryAfter: number;
|
||||
/**
|
||||
* The route being hit in this request
|
||||
*/
|
||||
route: string;
|
||||
/**
|
||||
* The time, in milliseconds, until the request-lock is reset
|
||||
* The time, in milliseconds, that will need to pass before the sublimit lock for the route resets, and requests that fall under a sublimit
|
||||
* can be retried
|
||||
*
|
||||
* This is only present on certain sublimits, and `0` otherwise
|
||||
*/
|
||||
sublimitTimeout: number;
|
||||
/**
|
||||
* The time, in milliseconds, until the route's request-lock is reset
|
||||
*/
|
||||
timeToReset: number;
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue