feat(cache): enhance error handling and logging for cache operations
- Added try-catch blocks to improve resilience in cache operations across services. - Integrated detailed error logging for better debugging. - Updated Redis reconnect strategy with exponential backoff and logging.
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
import { CacheModule } from "@nestjs/cache-manager";
|
import { CacheModule } from "@nestjs/cache-manager";
|
||||||
import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";
|
import {
|
||||||
|
Logger,
|
||||||
|
MiddlewareConsumer,
|
||||||
|
Module,
|
||||||
|
NestModule,
|
||||||
|
} from "@nestjs/common";
|
||||||
import { ConfigModule, ConfigService } from "@nestjs/config";
|
import { ConfigModule, ConfigService } from "@nestjs/config";
|
||||||
import { ScheduleModule } from "@nestjs/schedule";
|
import { ScheduleModule } from "@nestjs/schedule";
|
||||||
import { ThrottlerModule } from "@nestjs/throttler";
|
import { ThrottlerModule } from "@nestjs/throttler";
|
||||||
@@ -70,12 +75,24 @@ import { UsersModule } from "./users/users.module";
|
|||||||
isGlobal: true,
|
isGlobal: true,
|
||||||
imports: [ConfigModule],
|
imports: [ConfigModule],
|
||||||
inject: [ConfigService],
|
inject: [ConfigService],
|
||||||
useFactory: async (config: ConfigService) => ({
|
useFactory: async (config: ConfigService) => {
|
||||||
store: await redisStore({
|
const logger = new Logger("RedisCache");
|
||||||
url: `redis://${config.get("REDIS_HOST")}:${config.get("REDIS_PORT")}`,
|
return {
|
||||||
}),
|
store: await redisStore({
|
||||||
ttl: 600, // 10 minutes
|
url: `redis://${config.get("REDIS_HOST")}:${config.get("REDIS_PORT")}`,
|
||||||
}),
|
socket: {
|
||||||
|
reconnectStrategy: (retries) => {
|
||||||
|
const delay = Math.min(retries * 50, 2000);
|
||||||
|
logger.warn(
|
||||||
|
`Redis connection lost. Retrying in ${delay}ms (attempt ${retries})`,
|
||||||
|
);
|
||||||
|
return delay;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
ttl: 600, // 10 minutes
|
||||||
|
};
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
controllers: [AppController, HealthController],
|
controllers: [AppController, HealthController],
|
||||||
|
|||||||
@@ -15,8 +15,12 @@ export class CategoriesService {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
private async clearCategoriesCache() {
|
private async clearCategoriesCache() {
|
||||||
this.logger.log("Clearing categories cache");
|
try {
|
||||||
await this.cacheManager.del("categories/all");
|
this.logger.log("Clearing categories cache");
|
||||||
|
await this.cacheManager.del("categories/all");
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Error clearing categories cache: ${error.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAll() {
|
async findAll() {
|
||||||
|
|||||||
@@ -49,13 +49,18 @@ export class CrawlerDetectionMiddleware implements NestMiddleware {
|
|||||||
const userAgent = req.get("user-agent") || "unknown";
|
const userAgent = req.get("user-agent") || "unknown";
|
||||||
|
|
||||||
// Vérifier si l'IP est bannie
|
// Vérifier si l'IP est bannie
|
||||||
const isBanned = await this.cacheManager.get(`banned_ip:${ip}`);
|
try {
|
||||||
if (isBanned) {
|
const isBanned = await this.cacheManager.get(`banned_ip:${ip}`);
|
||||||
this.logger.warn(`Banned IP attempt: ${ip} -> ${method} ${url}`);
|
if (isBanned) {
|
||||||
res.status(403).json({
|
this.logger.warn(`Banned IP attempt: ${ip} -> ${method} ${url}`);
|
||||||
message: "Access denied: Your IP has been temporarily banned.",
|
res.status(403).json({
|
||||||
});
|
message: "Access denied: Your IP has been temporarily banned.",
|
||||||
return;
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Error checking ban status for IP ${ip}: ${error.message}`);
|
||||||
|
// On continue même en cas d'erreur Redis pour ne pas bloquer les utilisateurs légitimes
|
||||||
}
|
}
|
||||||
|
|
||||||
res.on("finish", async () => {
|
res.on("finish", async () => {
|
||||||
@@ -73,7 +78,11 @@ export class CrawlerDetectionMiddleware implements NestMiddleware {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Bannir l'IP pour 24h via Redis
|
// Bannir l'IP pour 24h via Redis
|
||||||
await this.cacheManager.set(`banned_ip:${ip}`, true, 86400000);
|
try {
|
||||||
|
await this.cacheManager.set(`banned_ip:${ip}`, true, 86400000);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Error banning IP ${ip}: ${error.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -34,8 +34,12 @@ export class ContentsService {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
private async clearContentsCache() {
|
private async clearContentsCache() {
|
||||||
this.logger.log("Clearing contents cache");
|
try {
|
||||||
await this.cacheManager.clear();
|
this.logger.log("Clearing contents cache");
|
||||||
|
await this.cacheManager.del("contents/all");
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Error clearing contents cache: ${error.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUploadUrl(userId: string, fileName: string) {
|
async getUploadUrl(userId: string, fileName: string) {
|
||||||
|
|||||||
@@ -33,8 +33,12 @@ export class UsersService {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
private async clearUserCache(username?: string) {
|
private async clearUserCache(username?: string) {
|
||||||
if (username) {
|
try {
|
||||||
await this.cacheManager.del(`users/profile/${username}`);
|
if (username) {
|
||||||
|
await this.cacheManager.del(`users/profile/${username}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Error clearing user cache: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user