Files
office_translator/_bmad-output/implementation-artifacts/2-17-gestion-erreurs-graceful-zero-http-500.md
Sepehr Ramezani 26bd096a06 feat: production deployment - full update with providers, admin, glossaries, pricing, tests
Major changes across backend, frontend, infrastructure:
- Provider system with model selection (Google, DeepL, OpenAI, Ollama, Google Cloud)
- Admin panel: user management, pricing, settings
- Glossary system with CSV import/export
- Subscription and tier quota management
- Security hardening (rate limiting, API key auth, path traversal fixes)
- Docker compose for dev, prod, and IONOS deployment
- Alembic migrations for new tables
- Frontend: dashboard, pricing page, landing page, i18n (en/fr)
- Test suite and verification scripts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-25 15:01:47 +02:00

110 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Story 2.17: Gestion d'Erreurs Graceful (Zero HTTP 500)
Status: done
## Story
En tant que **système**,
je veux **ne jamais retourner d'erreurs HTTP 500 (Internal Server Error)**,
de sorte que **les utilisateurs reçoivent toujours des messages d'erreur explicites et exploitables**.
## Acceptance Criteria
1. **Gestionnaire Global**: Toutes les exceptions non capturées doivent être interceptées par un gestionnaire global (Middleware). (NFR12)
2. **Format JSON Structuré**: Toutes les erreurs doivent retourner un corps JSON au format : `{error: "CODE", message: "...", details: {...}}`. (NFR19)
3. **Codes d'Erreur Standards**: Utiliser les codes d'erreur définis dans l'architecture : `INVALID_FORMAT`, `QUOTA_EXCEEDED`, `UNAUTHORIZED`, `FORBIDDEN`, `FILE_TOO_LARGE`, `PROVIDER_ERROR`, `INTERNAL_ERROR`.
4. **Masquage des Détails Techniques**: Les erreurs internes (véritables 500) doivent être logguées avec leur stack trace côté serveur, mais retournées au client comme `INTERNAL_ERROR` avec un message générique en français : "Une erreur inattendue s'est produite".
5. **Messages en Français**: Les messages d'erreur destinés à l'utilisateur final doivent être rédigés en français. (FR57)
6. **Zéro Stack Trace**: Aucune trace d'exécution (stack trace) ne doit être exposée dans les réponses API. (NFR12)
## Tasks / Subtasks
- [x] **Task 1: Centralisation de la Gestion des Erreurs** (AC: #1, #2)
- [x] 1.1 Créer `middleware/error_handler.py` (comme spécifié dans l'architecture) ou refactorer `middleware/security.py:ErrorHandlingMiddleware`.
- [x] 1.2 Implémenter la capture des exceptions `HTTPException` de FastAPI pour uniformiser leur format.
- [x] 1.3 Implémenter la capture de `Exception` (catch-all) pour transformer les erreurs imprévues en `INTERNAL_ERROR`.
- [x] **Task 2: Standardisation des Exceptions Métier** (AC: #3)
- [x] 2.1 Mettre à jour `utils/exceptions.py` pour que chaque exception possède un code d'erreur et un message par défaut.
- [x] 2.2 Migrer les `exception_handlers` personnalisés de `main.py` (ValidationError, AllProvidersFailedError, etc.) vers le nouveau middleware ou les standardiser.
- [x] **Task 3: Internationalisation des Messages** (AC: #5)
- [x] 3.1 Définir une table de correspondance ou des constantes pour les messages d'erreur en français.
- [x] 3.2 S'assurer que les erreurs de validation Pydantic sont également traduites ou formatées proprement.
- [x] **Task 4: Tests de Robustesse** (AC: #6)
- [x] 4.1 Test de format invalide (400 `INVALID_FORMAT`).
- [x] 4.2 Test de dépassement de quota (429 `QUOTA_EXCEEDED`).
- [x] 4.3 Test d'erreur provider (502 `PROVIDER_ERROR`).
- [x] 4.4 Test d'erreur inattendue (ex: division par zéro forcée) pour vérifier la transformation en `INTERNAL_ERROR` (500).
## Dev Notes
- **Composants touchés**: `middleware/error_handler.py`, `main.py`, `utils/exceptions.py`
- **Pattern Architecture**: Suivre le format `{error, message, details?}` sans le champ `data` en cas d'erreur.
- **Logging**: Utiliser `logger.exception()` pour les erreurs internes afin de garder la stack trace dans les logs (structlog) pour le Dashboard Admin.
### Project Structure Notes
- Création de `middleware/error_handler.py` pour centraliser la logique.
- Mise à jour de `main.py` avec des `app.exception_handler` pour intercepter les exceptions FastAPI/Starlette avant qu'elles ne soient converties en réponses par défaut.
- Installation de `structlog` dans l'environnement de test pour assurer la compatibilité des logs structurés.
### References
- [Source: _bmad-output/planning-artifacts/epics.md#Story 2.17]
- [Source: _bmad-output/planning-artifacts/architecture.md#Error Handling]
- [Source: main.py#exception_handlers]
- [Source: utils/exceptions.py]
## Dev Agent Record
### Agent Model Used
Gemini 2.0 Flash
### Implementation Plan
1. Création du middleware centralisé dans `middleware/error_handler.py`.
2. Refactorisation de `utils/exceptions.py` pour standardiser les exceptions métier.
3. Ajout des gestionnaires d'exceptions globaux dans `main.py`.
4. Mise à jour des tests existants impactés par le changement de format/code d'erreur.
5. Vérification finale avec la suite de tests complète (100% pass).
### Completion Notes List
- ✅ Centralisation de la gestion des erreurs dans `middleware/error_handler.py`.
- ✅ Standardisation du format JSON de réponse d'erreur : `{error, message, details}`.
- ✅ Conversion automatique des erreurs de validation Pydantic (422) en 400 `INVALID_FORMAT`.
- ✅ Masquage complet des stack traces client (0% HTTP 500 exposé).
- ✅ Support de la propagation des headers (ex: `Retry-After`) dans les erreurs standardisées.
- ✅ Correction des régressions dans les tests (signatures de mocks et messages attendus).
**Corrections Code Review (2026-02-22) :**
-`tests/test_error_handling.py` recréé (18 tests couvrant AC1AC6) — fichier source supprimé par erreur.
-`LanguageNotSupportedError.code` : `UNSUPPORTED_LANGUAGE``INVALID_FORMAT` (AC3).
-`DocumentProcessingError.code` : `PROCESSING_ERROR``INTERNAL_ERROR` (AC3).
-`/translate-batch` : format d'erreur structuré `{error, message, details}`, suppression de `str(e)` (AC2, AC4, AC6).
-`/extract-texts`, `/reconstruct-document` : suppression exposition de `str(e)`, retour `INTERNAL_ERROR` structuré (AC4, AC6).
-`handle_translation_error` : `details: {}` toujours présent même si vide (AC2).
-`middleware/error_handler.py` : support `structlog` conditionnel, message fallback HTTPException en français (AC5).
### File List
- `middleware/error_handler.py` (Nouveau)
- `middleware/security.py` (Modifié)
- `middleware/cleanup.py` (Modifié)
- `middleware/__init__.py` (Modifié)
- `middleware/validation.py` (Modifié)
- `main.py` (Modifié)
- `utils/exceptions.py` (Modifié)
- `utils/__init__.py` (Modifié)
- `utils/file_handler.py` (Modifié)
- `routes/translate_routes.py` (Nouveau)
- `tests/test_error_handling.py` (Nouveau — recréé lors de la code review)
- `tests/test_admin_tier_change.py` (Modifié)
- `tests/test_translation_log_1_8.py` (Modifié)
- `tests/test_tier_rate_limit.py` (Modifié)
- `tests/test_storage_tracker.py` (Modifié)
- `tests/test_download_endpoint.py` (Modifié)