Compare commits

..

3 Commits

Author SHA1 Message Date
Mathis HERRIOT
65b161dfc6 chore: bump version to 1.9.7
All checks were successful
CI/CD Pipeline / Valider backend (push) Successful in 2m13s
CI/CD Pipeline / Valider frontend (push) Successful in 2m24s
CI/CD Pipeline / Valider documentation (push) Successful in 2m30s
CI/CD Pipeline / Déploiement en Production (push) Successful in 6m1s
2026-02-09 09:55:41 +01:00
Mathis HERRIOT
75dca88164 style(app): reformat import statements and improve logging structure
- Simplified and condensed import declarations in `app.module.ts`.
- Enhanced error logging format in `crawler-detection.middleware.ts` for better readability.
2026-02-09 09:54:23 +01:00
Mathis HERRIOT
fe7683f5b1 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.
2026-02-09 09:52:40 +01:00
8 changed files with 59 additions and 24 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@memegoat/backend", "name": "@memegoat/backend",
"version": "1.9.6", "version": "1.9.7",
"description": "", "description": "",
"author": "", "author": "",
"private": true, "private": true,

View File

@@ -1,5 +1,5 @@
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 +70,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],

View File

@@ -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() {

View File

@@ -49,13 +49,20 @@ 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 +80,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}`);
}
} }
} }
}); });

View File

@@ -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) {

View File

@@ -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}`);
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@memegoat/frontend", "name": "@memegoat/frontend",
"version": "1.9.6", "version": "1.9.7",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@memegoat/source", "name": "@memegoat/source",
"version": "1.9.6", "version": "1.9.7",
"description": "", "description": "",
"scripts": { "scripts": {
"version:get": "cmake -P version.cmake GET", "version:get": "cmake -P version.cmake GET",