generated from gilles/template-webapp
5.4 KiB
5.4 KiB
Contrat d'erreurs API
Ce document définit le format standard des erreurs de l'API HomeStock.
Format des réponses d'erreur
Erreurs métier (HTTPException)
Toutes les erreurs métier utilisent fastapi.HTTPException et retournent :
{
"detail": "Message d'erreur lisible"
}
Erreurs de validation (Pydantic / FastAPI)
Les erreurs de validation des paramètres ou du corps de requête retournent automatiquement :
{
"detail": [
{
"type": "validation_error",
"loc": ["body", "name"],
"msg": "String should have at least 1 character",
"input": ""
}
]
}
Erreurs internes (500)
Le gestionnaire global (main.py) retourne :
{
"detail": "Message technique (dev) ou 'Erreur interne du serveur' (prod)",
"type": "internal_server_error"
}
En développement, le message contient les détails de l'exception. En production, le message est masqué pour la sécurité.
Codes HTTP utilisés
| Code | Signification | Usage |
|---|---|---|
| 200 | OK | GET, PUT, PATCH réussis |
| 201 | Created | POST réussi (création de ressource) |
| 204 | No Content | DELETE réussi (documents) |
| 400 | Bad Request | Données invalides (type de fichier, taille, auto-référence) |
| 404 | Not Found | Ressource inexistante (item, catégorie, emplacement, boutique, document, fichier physique) |
| 409 | Conflict | Conflit d'unicité (nom dupliqué, n° de série) ou dépendance empêchant la suppression |
| 422 | Unprocessable Entity | Erreur de validation Pydantic (format automatique FastAPI) |
| 500 | Internal Server Error | Exception non gérée |
Codes d'erreur par domaine
Items (/api/v1/items)
| Code HTTP | Situation | Message |
|---|---|---|
| 404 | Item non trouvé | Objet {id} non trouvé |
| 404 | Catégorie référencée inexistante | Catégorie {id} non trouvée |
| 404 | Emplacement référencé inexistant | Emplacement {id} non trouvé |
| 409 | N° de série déjà utilisé | Un objet avec le numéro de série '{sn}' existe déjà |
Catégories (/api/v1/categories)
| Code HTTP | Situation | Message |
|---|---|---|
| 404 | Catégorie non trouvée | Catégorie {id} non trouvée |
| 409 | Nom déjà utilisé | Une catégorie avec le nom '{name}' existe déjà |
| 409 | Suppression avec items liés | Impossible de supprimer : {n} objet(s) utilisent cette catégorie |
Emplacements (/api/v1/locations)
| Code HTTP | Situation | Message |
|---|---|---|
| 404 | Emplacement non trouvé | Emplacement {id} non trouvé |
| 404 | Parent inexistant | Emplacement parent {id} non trouvé |
| 400 | Auto-référence | Un emplacement ne peut pas être son propre parent |
| 409 | Suppression avec items liés | Impossible de supprimer : {n} objet(s) utilisent cet emplacement |
| 409 | Suppression avec sous-emplacements | Impossible de supprimer : cet emplacement a {n} sous-emplacement(s) |
Boutiques (/api/v1/shops)
| Code HTTP | Situation | Message |
|---|---|---|
| 404 | Boutique non trouvée | Boutique {id} non trouvée |
| 409 | Nom déjà utilisé | Une boutique avec le nom '{name}' existe déjà |
| 409 | Suppression avec items liés | Impossible de supprimer : {n} objet(s) sont associés à cette boutique |
Documents (/api/v1/documents)
| Code HTTP | Situation | Message |
|---|---|---|
| 404 | Item parent inexistant | Item {id} non trouvé |
| 404 | Document non trouvé | Document non trouvé |
| 404 | Fichier physique manquant | Fichier non trouvé sur le disque |
| 400 | Type MIME non autorisé | Type de fichier non autorisé : {mime}. Types acceptés : images (JPEG, PNG, GIF, WebP) et PDF |
| 400 | Photo sans image | Le type 'photo' nécessite un fichier image |
| 400 | Fichier trop volumineux | Fichier trop volumineux ({size} Mo). Taille max : 10 Mo |
Import CSV (/api/v1/import)
| Code HTTP | Situation | Message |
|---|---|---|
| 400 | Fichier non CSV | Le fichier doit être un CSV (.csv) |
| 400 | Indices de sélection invalides | Format d'indices invalide |
| 400 | Statut d'item invalide | Statut invalide : {status} |
Conventions
Champs obligatoires
Toute réponse d'erreur contient au minimum le champ detail (string ou array).
Messages
- Les messages sont en français, destinés à l'utilisateur final
- Ils incluent le contexte nécessaire (ID de la ressource, nom dupliqué, taille du fichier)
- En production (500), le message technique est masqué
Gestion côté client
Le frontend intercepte les erreurs via un intercepteur Axios (api/client.ts) qui log l'erreur dans la console. Le champ detail est affiché à l'utilisateur.
Schéma de réponse (schemas/common.py)
class ErrorResponse(BaseModel):
detail: str # Message d'erreur
type: str # Type d'erreur (ex: "internal_server_error")
class SuccessResponse(BaseModel):
message: str # Message de succès
id: int | None # ID de l'élément concerné