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(guard): Add support for throwing throttling exceptions #1443

Closed
Show file tree
Hide file tree
Changes from all commits
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
26 changes: 26 additions & 0 deletions src/throttler.guard.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { ThrottlerStorageRecord } from './throttler-storage-record.interface';

/**
* Interface describing the details of a rate limit applied by the ThrottlerGuard.
*/
export interface ThrottlerLimitDetail extends ThrottlerStorageRecord {
/**
* Time to live for the rate limit, in seconds. After this time has elapsed, the rate limit is removed.
*/
ttl: number;

/**
* Maximum number of requests allowed within the time period defined by `ttl`.
*/
limit: number;

/**
* Unique identifier for the rate limit. This field is used to group requests that share the same rate limit.
*/
key: string;

/**
* A string representation of the tracker object used to keep track of the incoming requests and apply the rate limit.
*/
tracker: string;
}
15 changes: 13 additions & 2 deletions src/throttler.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ThrottlerStorage } from './throttler-storage.interface';
import { THROTTLER_LIMIT, THROTTLER_SKIP, THROTTLER_TTL } from './throttler.constants';
import { InjectThrottlerOptions, InjectThrottlerStorage } from './throttler.decorator';
import { ThrottlerException, throttlerMessage } from './throttler.exception';
import { ThrottlerLimitDetail } from './throttler.guard.interface';

/**
* @publicApi
Expand Down Expand Up @@ -82,7 +83,14 @@ export class ThrottlerGuard implements CanActivate {
// Throw an error when the user reached their limit.
if (totalHits > limit) {
res.header('Retry-After', timeToExpire);
this.throwThrottlingException(context);
this.throwThrottlingException(context, {
limit,
ttl,
key,
tracker,
totalHits,
timeToExpire,
});
}

res.header(`${this.headerPrefix}-Limit`, limit);
Expand Down Expand Up @@ -123,7 +131,10 @@ export class ThrottlerGuard implements CanActivate {
* @throws {ThrottlerException}
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
protected throwThrottlingException(context: ExecutionContext): void {
protected throwThrottlingException(
context: ExecutionContext,
throttlerLimitDetail: ThrottlerLimitDetail,
): void {
throw new ThrottlerException(this.errorMessage);
}
}