Aller au contenu

Erreurs

Chaque réponse 4xx et 5xx de l’API Lisoloo utilise la même forme JSON. Basez vos branchements sur error_code, jamais sur message — les messages sont localisés et peuvent changer pour plus de clarté ; les codes font partie du contrat public.

{
"success": false,
"status_code": 400,
"error_code": "1101",
"message": "Invalid amount or recipient list",
"details": [
{
"field": "to[0]",
"message": "Must match E.164 format",
"code": "INVALID_PHONE_NUMBER"
}
],
"timestamp": "2026-05-27T10:15:00Z",
"request_id": "req_8f3a4c2e9b1d7a6f",
"retryable": false,
"retry_after": null
}
ChampTypeNotes
successboolToujours false en erreur. Garde facile : if (!body.success) { … }.
status_codeintReflète le statut HTTP.
error_codestringCode à quatre chiffres stable. Branchez là-dessus.
messagestringLisible. Localisé par Accept-Language. Pour les opérations, pas les utilisateurs finaux.
detailsarray | nullDécomposition au niveau du champ pour les erreurs de validation (1110).
timestampISO 8601Heure serveur de génération.
request_idstringÀ citer en contactant le support.
retryablebooltrue pour les échecs transitoires. Ne jamais auto-retry si false.
retry_afterint | nullSecondes à attendre si retryable: true (et 429).

Le premier chiffre groupe la cause :

PlageGroupeExemples
10011005Authentification1001 INVALID_APP_KEY, 1004 APP_SUSPENDED
11011110Validation de la requête1101 INVALID_RECIPIENTS, 1104 INVALID_PHONE_NUMBER, 1109 MISSING_REQUIRED_FIELD
12011205Logique métier1202 INSUFFICIENT_BALANCE, 1203 RECIPIENT_LIMIT_EXCEEDED
13011305Sécurité et limites1301 RATE_LIMIT_EXCEEDED
14011405Serveur / système1401 INTERNAL_SERVER_ERROR, 1402 SERVICE_UNAVAILABLE
15011505Opérateur / SMS1502 SMS_REJECTED_BY_CARRIER, 1503 SMS_TIMEOUT

Le catalogue complet avec remédiation est au catalogue d’erreurs.

function handleLisolooError(body: {
error_code: string;
message: string;
retryable: boolean;
retry_after: number | null;
}) {
switch (body.error_code) {
case "1001": // INVALID_APP_KEY
case "1004": // APP_SUSPENDED
// Stop. Pas de retry. Remonter aux opérations.
throw new AuthenticationFailed(body.message);
case "1101": // INVALID_RECIPIENTS
case "1104": // INVALID_PHONE_NUMBER
case "1109": // MISSING_REQUIRED_FIELD
// Mauvaise entrée chez nous. Corriger et ne pas retry le même body.
throw new ValidationError(body.message);
case "1202": // INSUFFICIENT_BALANCE
// Remonter au tableau de bord, alerter ops, pas de retry.
throw new BalanceExhausted(body.message);
case "1301": // RATE_LIMIT_EXCEEDED
// Respecter retry_after.
return scheduleRetry(body.retry_after ?? 60);
case "1402": // SERVICE_UNAVAILABLE
case "1503": // SMS_TIMEOUT
if (body.retryable) {
return scheduleRetry(body.retry_after ?? 30);
}
throw new ProcessorFailure(body.message);
default:
throw new UnknownError(body.error_code, body.message);
}
}

Certains codes correspondent à plusieurs statuts HTTP selon le contexte (par exemple 1004 APP_SUSPENDED est 403, tandis que 1001 INVALID_APP_KEY est 401). Le statut HTTP est la catégorie large ; error_code est la cause spécifique. Utilisez le statut HTTP pour le routage à travers le middleware (échecs d’auth vers un handler, échecs de validation vers un autre) ; utilisez error_code pour la logique réelle.

HTTPSignification
400Échec de validation. Pas de retry.
401En-tête d’auth manquant ou invalide. Pas de retry.
402Paiement requis (solde). Pas de retry.
403Authentifié mais interdit (clé suspendue). Pas de retry.
404Ressource introuvable (par exemple message_id inconnu).
429Limité. Respecter Retry-After.
500Erreur serveur. Retry sûr une fois avec backoff exponentiel.
502 / 503Problème upstream / opérateur. Retry sûr.

Quand la passerelle renvoie 1110 INVALID_FIELD_FORMAT (ou 1109 MISSING_REQUIRED_FIELD), le tableau details porte une entrée par champ échoué :

{
"error_code": "1110",
"message": "Field validation failed",
"details": [
{ "field": "to[2]", "message": "Must match E.164 format", "code": "INVALID_PHONE_NUMBER" },
{ "field": "message", "message": "Must be 1-1600 characters", "code": "INVALID_LENGTH" },
{ "field": "scheduled_dates[0].time", "message": "Must be HH:mm", "code": "INVALID_TIME_FORMAT" }
]
}

Le chemin field utilise une notation pointée style JSONPointer avec [n] pour les indices de tableau. Itérez details pour afficher les erreurs par champ dans votre UI.