# Les erreurs avec problem+json

Le code de statut dit **qu'il** y a une erreur. Le body doit dire **laquelle**, et comment la corriger. Plutôt que d'inventer un format par API, il existe un standard : `application/problem+json`.

### Le format

```http
HTTP/1.1 409 Conflict
Content-Type: application/problem+json

{
  "type": "https://api-ritif.example/problems/order-not-cancellable",
  "title": "La commande ne peut plus être annulée",
  "status": 409,
  "detail": "La commande 42 est en préparation. Le shaker tourne déjà.",
  "instance": "/v1/orders/42"
}
```

<table id="bkmrk-champr%C3%B4le-typeune-ur"><thead><tr><th>Champ</th><th>Rôle</th></tr></thead><tbody><tr><td>`type`</td><td>Une URI qui identifie le **type** d'erreur. Idéalement, une page de documentation qui l'explique. Par défaut : `about:blank`.</td></tr><tr><td>`title`</td><td>Un résumé court, le même pour toutes les erreurs de ce type.</td></tr><tr><td>`status`</td><td>Le code de statut HTTP, répété pour faciliter la lecture.</td></tr><tr><td>`detail`</td><td>L'explication propre à **cette** occurrence, lisible par un humain.</td></tr><tr><td>`instance`</td><td>Une URI qui identifie cette occurrence précise (la ressource concernée, ou un identifiant de log).</td></tr></tbody></table>

Tous les champs sont facultatifs, mais `type`, `title` et `status` sont un minimum raisonnable.

### Les extensions

On peut ajouter ses propres champs. Le cas le plus courant : les erreurs de validation, avec la liste des champs en faute.

```http
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json

{
  "type": "https://api-ritif.example/problems/validation-error",
  "title": "Données invalides",
  "status": 422,
  "detail": "La requête contient 2 erreurs.",
  "errors": [
    {"field": "rating", "message": "doit être compris entre 1 et 5"},
    {"field": "comment", "message": "ne doit pas dépasser 500 caractères"}
  ]
}
```

<p class="callout success">Le client peut afficher chaque message sous le bon champ du formulaire, sans parser une phrase.</p>

### Les bonnes pratiques

- Le même format pour **toutes** les erreurs de l'API, y compris les `404` et les `500`.
- Un `detail` qui dit quoi corriger : « la note doit être comprise entre 1 et 5 », pas « erreur de validation ».
- Jamais d'informations internes dans une erreur.

<p class="callout warning">Ceci n'est pas un message d'erreur, c'est une fuite d'informations :  
`{"error": "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'prix' in /var/www/api/models/Cocktail.php line 42"}`  
Un attaquant y apprend votre base de données, votre langage, votre arborescence et le nom de vos colonnes. Loggez le détail côté serveur, renvoyez un message neutre au client.</p>