feat(backend): report Retry-After
if client hit rate limit (#13949)
* feat(backend): report `Retry-After` if client hit rate limit * refactor(backend): fix lint error
This commit is contained in:
@@ -73,6 +73,16 @@ export class ApiCallService implements OnApplicationShutdown {
|
||||
reply.header('WWW-Authenticate', `Bearer realm="Misskey", error="insufficient_scope", error_description="${err.message}"`);
|
||||
}
|
||||
statusCode = statusCode ?? 403;
|
||||
} else if (err.code === 'RATE_LIMIT_EXCEEDED') {
|
||||
const info: unknown = err.info;
|
||||
const unixEpochInSeconds = Date.now();
|
||||
if (typeof(info) === 'object' && info && 'resetMs' in info && typeof(info.resetMs) === 'number') {
|
||||
const cooldownInSeconds = Math.ceil((info.resetMs - unixEpochInSeconds) / 1000);
|
||||
// もしかするとマイナスになる可能性がなくはないのでマイナスだったら0にしておく
|
||||
reply.header('Retry-After', Math.max(cooldownInSeconds, 0).toString(10));
|
||||
} else {
|
||||
this.logger.warn(`rate limit information has unexpected type ${typeof(err.info?.reset)}`);
|
||||
}
|
||||
} else if (!statusCode) {
|
||||
statusCode = 500;
|
||||
}
|
||||
@@ -308,12 +318,17 @@ export class ApiCallService implements OnApplicationShutdown {
|
||||
if (factor > 0) {
|
||||
// Rate limit
|
||||
await this.rateLimiterService.limit(limit as IEndpointMeta['limit'] & { key: NonNullable<string> }, limitActor, factor).catch(err => {
|
||||
throw new ApiError({
|
||||
message: 'Rate limit exceeded. Please try again later.',
|
||||
code: 'RATE_LIMIT_EXCEEDED',
|
||||
id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef',
|
||||
httpStatusCode: 429,
|
||||
});
|
||||
if ('info' in err) {
|
||||
// errはLimiter.LimiterInfoであることが期待される
|
||||
throw new ApiError({
|
||||
message: 'Rate limit exceeded. Please try again later.',
|
||||
code: 'RATE_LIMIT_EXCEEDED',
|
||||
id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef',
|
||||
httpStatusCode: 429,
|
||||
}, err.info);
|
||||
} else {
|
||||
throw new TypeError('information must be a rate-limiter information.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user