Erreurs & reprises
Une erreur d’API MADATA porte toujours deux choses : un code, que votre programme lit, et un message, qu’un humain lit. Savoir lequel des deux regarder fait gagner beaucoup de temps.
01La forme XML-RPC
Un appel en échec renvoie une Fault : un code entier et une
chaîne. La plupart des bibliothèques la lèvent comme une exception.
import xmlrpc.client
try:
models.execute_kw(DB, uid, CLE, 'account.move', 'unlink', [[1042]])
except xmlrpc.client.Fault as f:
print(f.faultCode) # 2
print(f.faultString) # "warning -- UserError\n\nVous ne pouvez pas
# supprimer une piece comptabilisee."
| Code | Signification | Ce qu’il faut en faire |
|---|---|---|
1 | Erreur applicative. Le faultString contient la trace. | Journaliser et alerter : c’est inattendu. |
2 | Avertissement métier : règle de gestion, donnée manquante, état incompatible. | Le message est destiné à un humain. Le montrer tel quel. |
3 | Accès refusé : identifiants invalides ou expirés. | Rejouer authenticate une fois ; si cela échoue encore, la clé est révoquée. |
4 | Droit insuffisant sur le modèle ou l’enregistrement. | Ne pas réessayer : c’est une question de droits, pas de réseau. |
02La forme JSON-RPC
En JSON, une erreur arrive en HTTP 200 avec une clé
error. Tester le code HTTP ne suffit donc pas : testez la
présence de error.
{"jsonrpc": "2.0", "id": null,
"error": {
"code": 200,
"message": "Madata Server Error",
"data": {
"name": "madata.exceptions.UserError",
"message": "Vous ne pouvez pas supprimer une piece comptabilisee.",
"arguments": ["Vous ne pouvez pas supprimer une piece comptabilisee."],
"debug": "Traceback (most recent call last): ...",
"context": {}
}}}
| Champ | À quoi il sert |
|---|---|
error.code | 200 erreur applicative · 100 session expirée · 404 chemin inconnu. |
error.data.message | Le message à montrer. C’est lui que vous affichez, pas error.message. |
error.data.name | Le type d’erreur, en identifiant machine. Sert à décider quoi faire. |
error.data.arguments | Les éléments du message, séparés. Pratique pour un affichage sur mesure. |
error.data.debug | La trace technique. À journaliser, jamais à montrer à un utilisateur. |
UserError et
ValidationError : une règle de gestion, le message est
utilisable tel quel. AccessError : un droit manque.
AccessDenied : les identifiants sont refusés.
MissingError : l’enregistrement visé n’existe plus.
03Les cas courants
| Symptôme | Cause la plus fréquente |
|---|---|
authenticate renvoie false | Base autre que prod_<espace>, ou clé révoquée, ou mot de passe utilisé alors que la double authentification est active. |
| « Accès refusé » sur un modèle | Le porteur de la clé n’a pas l’application concernée dans ses droits. |
| Une liste vide alors que l’écran montre des lignes | Périmètre de sociétés différent : passez allowed_company_ids. |
| Une ligne « manquante » après création | Elle est archivée. Relisez avec context: {active_test: False}. |
| « Champ obligatoire manquant » | Demandez à l’espace ce qu’il attend : default_get et fields_get. |
| L’appel est coupé après quelques minutes | La limite de durée d’un appel. Paginez ou découpez le traitement. |
503 avec Retry-After | L’espace est en cours de mise à jour. Attendez le délai indiqué et reprenez. |
04Reprendre proprement
Trois familles, trois conduites.
| Famille | Conduite |
|---|---|
Passager : 503, coupure réseau, délai dépassé. | Réessayer, en espaçant les tentatives et en respectant Retry-After. Au-delà de cinq essais, alerter. |
Métier : UserError, ValidationError. | Ne jamais réessayer à l’identique : la même requête donnera la même réponse. Corriger la donnée, ou remonter le message. |
Droits : AccessError, AccessDenied. | Arrêter. Une boucle de tentatives sur une clé révoquée ne fait que remplir les journaux. |
Un
create coupé par un délai réseau a peut-être abouti côté
espace. Avant de rejouer une écriture, cherchez si elle a eu lieu : voir
ne pas créer deux fois.
05Ce que la réponse dit, et ce qu’elle ne dit pas
Toutes les réponses de l’API nomment la plateforme
MADATA : le libellé d’erreur générique est
« Madata Server Error », l’expiration de session
« Madata Session Expired », les types d’erreur sont préfixés
madata.exceptions., et common.about() renvoie
"Madata. See https://madata.africa". Aucune réponse ne nomme
un autre éditeur.
Le champ server_version vaut "17.0" : c’est la
version du protocole d’appel, celle que les bibliothèques
clientes comparent pour savoir comment parler. Elle ne bouge pas d’une mise
à jour à l’autre et ne désigne aucune marque. La version de votre espace,
elle, s’affiche dans les paramètres.
Si une réponse de l’API vous montre autre chose que MADATA, c’est un défaut : signalez-le au support avec l’appel exact et la réponse reçue.
06Journaliser du bon côté
Côté espace, chaque écriture laisse une trace attachée à l’utilisateur
porteur de la clé : c’est ce qui permet au support de reconstituer une
séquence. Côté programme, gardez pour chaque appel en échec le modèle, la
méthode, les arguments et le data.debug ou le
faultString complet. Ce sont exactement les éléments qu’on
vous demandera, et ce sont ceux qu’on n’a plus quand on ne les a pas
enregistrés.