Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: expose Retry-After and sublimit timeouts in RatelimitData #9864

Merged
merged 4 commits into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion packages/rest/src/lib/errors/RateLimitError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

/**
Expand Down
12 changes: 8 additions & 4 deletions packages/rest/src/lib/handlers/BurstHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
24 changes: 16 additions & 8 deletions packages/rest/src/lib/handlers/SequentialHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`);
Expand Down Expand Up @@ -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',
Expand All @@ -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
Expand Down
10 changes: 10 additions & 0 deletions packages/rest/src/lib/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,20 @@ export interface RateLimitData {
* The HTTP method being performed
*/
method: string;
/**
* The time, in milliseconds, that will need to pass before this request can be retried
*/
retryAfter: number;
/**
* The route being hit in this request
*/
route: string;
/**
* The time, in milliseconds, that will need to pass before this request can be retried
ckohen marked this conversation as resolved.
Show resolved Hide resolved
*
* This is only present on certain sublimits, and `0` otherwise
*/
sublimitTimeout: number;
ckohen marked this conversation as resolved.
Show resolved Hide resolved
/**
* The time, in milliseconds, until the request-lock is reset
*/
Expand Down