Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 12x 12x 12x 12x 12x 1x 1x 1x 1x | import { Injectable, ExecutionContext, Inject } from '@nestjs/common';
import { ThrottlerGuard, ThrottlerException, ThrottlerModuleOptions, ThrottlerStorage } from '@nestjs/throttler';
import { Reflector } from '@nestjs/core';
import { LoggerService } from '@app/common/services/logger.service';
@Injectable()
export class ThrottlerLoggerGuard extends ThrottlerGuard {
constructor(
@Inject('THROTTLER_OPTIONS') options: ThrottlerModuleOptions,
@Inject('THROTTLER_STORAGE') storageService: ThrottlerStorage,
reflector: Reflector,
private readonly logger: LoggerService,
) {
super(options, storageService, reflector);
}
async canActivate(context: ExecutionContext): Promise<boolean> {
// In test runs, disable throttling to ensure deterministic, non-flaky tests
if (process.env.TEST_MODE === '1' || process.env.NODE_ENV === 'test') {
return true;
}
return super.canActivate(context) as any;
}
protected async throwThrottlingException(context: ExecutionContext, throttlerLimitDetail: any): Promise<void> {
const req = this.getRequestResponse(context).req;
// Try to get userId if available (JWT, session, etc.)
const userId = req.user?.id || req.user?.sub || undefined;
this.logger.warn('Rate limit exceeded', {
ip: req.ip,
path: req.originalUrl || req.url,
userId,
method: req.method,
limit: throttlerLimitDetail?.limit,
ttl: throttlerLimitDetail?.ttl,
timestamp: new Date().toISOString(),
});
throw new ThrottlerException('Too many requests. Please try again later.');
}
} |