Erreurs
Format RFC 7807 des erreurs, codes métier les plus fréquents et conduite à tenir.
Format
Toute erreur métier est renvoyée au format Problem Details (RFC 7807), type
application/problem+json :
{
"status": 400,
"title": "Action impossible",
"detail": "Proposition verrouillée : un lien de paiement est en cours",
"exception": "PROPOSAL_LOCKED_FOR_PAYMENT",
"instance": "/api/v1/provider/contracts/1273be1c-.../duration",
"details": {
"PÉRIODE DEMANDÉE": "07/11/2026 → 06/02/2027"
}
}| Champ | Description |
|---|---|
status | Code HTTP |
title | Titre lisible, dérivé du statut (voir ci-dessous) |
detail | Message métier, en français |
exception | Code d'erreur stable, à utiliser dans votre code |
instance | Chemin appelé |
details | Paires libellé / valeur complémentaires (optionnel) |
| autres clés | Propriétés spécifiques, par exemple endorsementId |
status | title |
|---|---|
| 400 | Action impossible |
| 401 | Connexion requise |
| 403 | Accès refusé |
| 404 | Élément introuvable |
| 409 | Opération en conflit |
| 502, 503, 504 | Service momentanément indisponible |
| autre | Une erreur est survenue |
Les erreurs de validation de corps (champ obligatoire manquant, format de châssis invalide…)
renvoient 400 avec le message de la contrainte, par exemple « Champ obligatoire » ou « Le format du
numéro de châssis est invalide ».
Codes fréquents
Authentification
exception | HTTP | Sens |
|---|---|---|
IDENTITY_AUTHENTICATION_FAILED | 401 / 502 | Identifiants refusés ou service d'authentification en erreur |
IDENTITY_SERVICE_UNAVAILABLE | 503 | Service d'authentification injoignable |
Souscription
exception | Sens | Que faire |
|---|---|---|
CONTRACT_NOT_FOUND | Contrat inconnu ou hors périmètre | Vérifier l'identifiant et le rattachement du compte |
CONTRACT_NOT_MODIFIABLE | La proposition n'est plus en DRAFT | Les modifications (durée, véhicules, parties) ne sont possibles qu'avant paiement |
PROPOSAL_LOCKED_FOR_PAYMENT | Un lien de paiement est en cours | Annuler les liens (…/payment/cancel) avant de modifier |
PENDING_PAYMENT_LINK_ON_SHARED_VEHICLE | Un véhicule est déjà dans une proposition en attente de paiement | Attendre ou annuler ce paiement |
VEHICLE_NOT_FOUND | vehicleId inconnu ou invisible | Créer le véhicule ou vérifier son rattachement |
VEHICLE_ALREADY_INSURED, VEHICLE_NOT_ELIGIBLE | Véhicule déjà couvert ou non éligible | Vérifier le parc du souscripteur |
VEHICLE_SEAT_ERROR | numberOfSeats absent ou nul | Renseigner le nombre de places |
TARIFF_NOT_FOUND, TARIFF_CALCULATION_ERROR | Pas de grille pour la durée / le nombre de places | Vérifier durée et caractéristiques du véhicule |
DURATION_NOT_FOUND, DURATION_NOT_ACTIVE, INACTIVE_DURATION | durationCode inconnu ou inactif | Relire GET /provider/durations |
EFFECTIVE_DATE_IN_PAST, EFFECTIVE_DATE_TOO_FAR, INVALID_EFFECTIVE_DATE | Date d'effet hors bornes | Corriger effectiveDate |
SUBSCRIBER_NOT_FOUND, INSURED_NOT_FOUND, REFERRER_NOT_FOUND | Partie inconnue | Créer la partie ou corriger l'identifiant |
LNK_BROKER_COMPANY_NOT_FOUND | Partenariat inconnu ou non autorisé | Relire GET /provider/lnk-broker-companies |
ENDORSEMENT_NOT_FOUND | Avenant inconnu, ou aucun avenant QUOTE à payer | Vérifier l'identifiant ou recalculer la prime |
ENDORSEMENT_NOT_ALLOWED, INVALID_CONTRACT_STATUS | Avenant impossible dans l'état du contrat | Consulter le statut du contrat |
REF_VEHICLE_BRAND_ALREADY_EXISTS, REF_VEHICLE_MODEL_ALREADY_EXISTS | Code référentiel déjà pris | Réutiliser l'existant |
DOCUMENTS_FOLDER_NOT_SET | Le contrat n'a pas encore de dossier documentaire | Réessayer après émission |
GENERIC_ERROR | Règle métier détaillée dans detail | Lire detail |
États
Les erreurs du moteur d'états portent le code GENERIC_ERROR avec un detail explicite :
detail | Cause |
|---|---|
Source inconnue : X | sourceCode n'est pas l'un des 9 codes de source |
Définition inconnue : X | definitionCode absent du catalogue |
Colonne inexistante : RECEIPTS.foo | fieldName inconnu pour la source |
Champ de filtre inconnu, Champ non filtrable | Filtre sur un champ inexistant ou filterable=false |
Champ de regroupement inconnu, Champ non groupable | grouping sur un champ groupable=false |
Champ de tri inconnu, Champ non triable | sorting.fieldName invalide |
Opérateur manquant sur le filtre | operator absent |
Valeur de filtre invalide pour X : v | Valeur non convertible dans le type du champ |
Ancre temporelle inconnue : X | scope.basedOn n'est pas une ancre de la source |
Le mode récapitulatif nécessite au moins un champ de regroupement | options.aggregated=true sans grouping |
Une colonne calculée doit porter un nom, Colonne calculée sans formule | Colonne CALCULATED incomplète |
Aucune colonne sélectionnée | Spécification vide |
Format non autorisé pour cet état | format hors de formats de la définition |
PDF limité à 25000 lignes (…) | Trop de lignes pour un PDF : réduire la période ou passer en XLSX/CSV |
Génération : fournir modelId, definitionCode ou une spécification | Corps de génération vide |
Modèle introuvable, Exécution introuvable, Aucun fichier archivé pour l'exécution | Identifiant inconnu ou fichier purgé |
Un modèle avec ce nom existe déjà | Nom de modèle en doublon |
Jour du mois invalide, endDate requis pour le mode UNTIL_DATE, occurrences requis pour le mode AFTER_OCCURRENCES | Planification incohérente |
Gérer les erreurs dans le code
async function call(path: string, init: RequestInit = {}) {
const res = await fetch(`${API}${path}`, {
...init,
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', ...init.headers },
});
if (res.ok) return res.status === 204 ? null : res.json();
const problem = await res.json().catch(() => ({}));
switch (res.status) {
case 401: await refreshToken(); return call(path, init); // [!code highlight]
case 400: throw new Error(`${problem.exception}: ${problem.detail}`); // [!code highlight]
case 404: throw new Error(`Introuvable: ${problem.detail}`);
default: throw new Error(`HTTP ${res.status} ${problem.title ?? ''}`);
}
}Journalisez toujours exception, detail et instance : ce sont les trois informations que le
support ASACI demande en premier.