mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 13:35:42 +09:00
fix(slowmode): stop the local cooldown from outgrowing the channel setting (#1795)
This commit is contained in:
1 parent
8f4f9a8601
commit
631bc2307a
15 files changed
+497
-147
No files matched your search
@@ -1,25 +1,15 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
|
||||
import {
|
||||
sanitizeRetryAfterDecimalSeconds,
|
||||
sanitizeRetryAfterSeconds,
|
||||
} from '@fluxer/errors/src/domains/core/RetryAfterSeconds';
|
||||
import {ThrottledError} from '@fluxer/errors/src/domains/core/ThrottledError';
|
||||
import type {FluxerErrorData} from '@fluxer/errors/src/FluxerError';
|
||||
|
||||
type RateLimitScope = 'global' | 'shared' | 'user';
|
||||
|
||||
function sanitizeRetryAfter(value: number | undefined | null): number {
|
||||
if (value == null || !Number.isFinite(value) || value < 0) {
|
||||
return 1;
|
||||
}
|
||||
return Math.max(1, Math.ceil(value));
|
||||
}
|
||||
|
||||
function sanitizeRetryAfterDecimal(value: number | undefined | null, fallback: number): number {
|
||||
if (value == null || !Number.isFinite(value) || value < 0) {
|
||||
return fallback;
|
||||
}
|
||||
return Math.max(0.001, value);
|
||||
}
|
||||
|
||||
function sanitizeResetTime(resetTime: Date): number {
|
||||
const timestamp = resetTime.getTime();
|
||||
if (!Number.isFinite(timestamp)) {
|
||||
@@ -64,8 +54,8 @@ export class RateLimitError extends ThrottledError {
|
||||
bucketHash?: string;
|
||||
scope?: RateLimitScope;
|
||||
}) {
|
||||
const safeRetryAfter = sanitizeRetryAfter(retryAfter);
|
||||
const safeRetryAfterDecimal = sanitizeRetryAfterDecimal(retryAfterDecimal, safeRetryAfter);
|
||||
const safeRetryAfter = sanitizeRetryAfterSeconds(retryAfter);
|
||||
const safeRetryAfterDecimal = sanitizeRetryAfterDecimalSeconds(retryAfterDecimal, safeRetryAfter);
|
||||
const safeResetTimestamp = sanitizeResetTime(resetTime);
|
||||
const safeLimit = Number.isFinite(limit) && limit > 0 ? limit : 1;
|
||||
const safeResetAfterDecimal =
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
export function sanitizeRetryAfterSeconds(value: number | undefined | null): number {
|
||||
if (value == null || !Number.isFinite(value) || value < 0) {
|
||||
return 1;
|
||||
}
|
||||
return Math.max(1, Math.ceil(value));
|
||||
}
|
||||
|
||||
export function sanitizeRetryAfterDecimalSeconds(value: number | undefined | null, fallback: number): number {
|
||||
if (value == null || !Number.isFinite(value) || value < 0) {
|
||||
return fallback;
|
||||
}
|
||||
return Math.max(0.001, value);
|
||||
}
|
||||
@@ -2,22 +2,28 @@
|
||||
|
||||
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
|
||||
import {BadRequestError} from '@fluxer/errors/src/domains/core/BadRequestError';
|
||||
import {
|
||||
sanitizeRetryAfterDecimalSeconds,
|
||||
sanitizeRetryAfterSeconds,
|
||||
} from '@fluxer/errors/src/domains/core/RetryAfterSeconds';
|
||||
|
||||
export class SlowmodeRateLimitError extends BadRequestError {
|
||||
constructor({
|
||||
retryAfter,
|
||||
retryAfterDecimal,
|
||||
}: {
|
||||
retryAfter: number;
|
||||
retryAfter: number | undefined;
|
||||
retryAfterDecimal?: number;
|
||||
}) {
|
||||
const safeRetryAfter = sanitizeRetryAfterSeconds(retryAfter);
|
||||
const safeRetryAfterDecimal = sanitizeRetryAfterDecimalSeconds(retryAfterDecimal, safeRetryAfter);
|
||||
super({
|
||||
code: APIErrorCodes.SLOWMODE_RATE_LIMITED,
|
||||
data: {
|
||||
retry_after: retryAfterDecimal ?? retryAfter,
|
||||
retry_after: safeRetryAfterDecimal,
|
||||
},
|
||||
headers: {
|
||||
'Retry-After': retryAfter.toString(),
|
||||
'Retry-After': safeRetryAfter.toString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user