diff --git a/CHANGELOG.md b/CHANGELOG.md index d8e608e..252c0fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,3 +14,10 @@ - 5xx: erreurs internes ou partenaires (non applicatives) - Documentation et tests mis à jour pour couvrir “JSON invalide -> 400”. - CI: utiliser `ci: docker_tag=ext` pour builder/pusher l’image. + +## v1.0.3 + +- IdNot: renforcement de la gestion d’erreurs applicatives (4xx) dans `IdNotController.authenticate`. + - Laisse désormais passer toute erreur avec `statusCode` 4xx même si l’instance n’est pas exactement celle des classes locales. + - Fallback sur `name` (BusinessRuleError, ForbiddenError, UnauthorizedError, ValidationError) pour tolérer les divergences d’instances. +- Objectif: éviter les 502 lorsqu’un cas fonctionnel (ex: utilisateur non rattaché) survient, et renvoyer le bon 4xx. diff --git a/docs/analyse.md b/docs/analyse.md index b142fd1..cc24960 100644 --- a/docs/analyse.md +++ b/docs/analyse.md @@ -36,6 +36,8 @@ Analyse synthétique de `lecoffre-back-mini` (Express + TypeScript). - `403`: utilisateur non rattaché à une étude (ForbiddenError) - `5xx`: erreurs internes ou partenaires (ExternalServiceError) +Note: dans `IdNotController.authenticate`, toute erreur possédant un `statusCode` 4xx (ou un `name` applicatif connu) est relancée telle quelle afin d’éviter un fallback en 502. + ### Dépendances clés - **HTTP**: `express`, `cors` - **Infra**: `pg`, `dotenv` diff --git a/package.json b/package.json index 6dbd952..3117337 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lecoffre-back-mini", - "version": "1.0.2", + "version": "1.0.3", "description": "Mini serveur avec une route /api/ping", "main": "dist/server.js", "scripts": { diff --git a/src/controllers/idnot.controller.ts b/src/controllers/idnot.controller.ts index 6ba6f40..86f9345 100644 --- a/src/controllers/idnot.controller.ts +++ b/src/controllers/idnot.controller.ts @@ -174,11 +174,25 @@ export class IdNotController { }); // Laisser passer les erreurs applicatives connues (4xx) pour éviter un 502 côté client + // Approche robuste: on tolère les divergences d'instance en vérifiant le statusCode et le nom + const maybeStatus = (error as any)?.statusCode; + const maybeName = (error as any)?.name as string | undefined; + + // 1) Si une erreur possède un statusCode 4xx, on la relaisse passer + if (typeof maybeStatus === 'number' && maybeStatus >= 400 && maybeStatus < 500) { + throw error; + } + + // 2) Si le nom correspond à une erreur applicative connue, on la relaisse passer if ( error instanceof BusinessRuleError || error instanceof ForbiddenError || error instanceof UnauthorizedError || - error instanceof ValidationError + error instanceof ValidationError || + maybeName === 'BusinessRuleError' || + maybeName === 'ForbiddenError' || + maybeName === 'UnauthorizedError' || + maybeName === 'ValidationError' ) { throw error; } diff --git a/src/middleware/error-handler.ts b/src/middleware/error-handler.ts index 75eb214..bfa379a 100644 --- a/src/middleware/error-handler.ts +++ b/src/middleware/error-handler.ts @@ -9,7 +9,7 @@ export const errorHandler = ( next: NextFunction ): void => { const requestId = req.headers['x-request-id'] as string || 'unknown'; - + // If it's already an AppError, use it directly if (error instanceof AppError) { Logger.error('Application error occurred', { @@ -43,7 +43,7 @@ export const errorHandler = ( undefined, requestId ); - + Logger.error('Validation error', { requestId, originalError: error.message, @@ -63,7 +63,7 @@ export const errorHandler = ( undefined, requestId ); - + Logger.error('Unauthorized access attempt', { requestId, error: error.message, @@ -161,11 +161,11 @@ export const asyncHandler = (fn: Function) => { // Request ID middleware export const requestIdMiddleware = (req: Request, res: Response, next: NextFunction) => { - const requestId = req.headers['x-request-id'] as string || + const requestId = req.headers['x-request-id'] as string || `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; - + req.headers['x-request-id'] = requestId; res.setHeader('X-Request-ID', requestId); - + next(); }; diff --git a/tests/analyse.md b/tests/analyse.md index 6fef9ea..e89c96d 100644 --- a/tests/analyse.md +++ b/tests/analyse.md @@ -19,3 +19,6 @@ Axes de tests pour `lecoffre-back-mini` (sans exemples d’implémentation). - Vérifier POST `/api/v1/idnot/auth` avec un code long dans le corps JSON (`{ code }`) retourne un statut applicatif (4xx/5xx) mais pas 502. - Vérifier qu’un corps JSON invalide (ex: JSON mal formé) renvoie `400`. - Vérifier qu’un GET/POST avec segment d’URL trop long n’est plus utilisé par le front. + +Focus régression v1.0.3: +- Cas « utilisateur non rattaché à une étude » doit renvoyer `403` (plus de 502).