Gestion des erreurs
Chatbotaurus gère les erreurs à plusieurs niveaux : une énumération d'erreurs commune à tout le backend, une enveloppe JSON stable côté API, des codes JSON-RPC pour le transport MCP, un disjoncteur pour les services en aval et une dégradation par paliers du moteur d'IA.
À la fin, vous saurez lire un code d'erreur renvoyé par l'API ou par le transport MCP et savoir où chercher la cause.
Erreurs de l'API REST
Les handlers de forge-api renvoient des ForgeError
(crates/forge-core/src/error.rs). Chaque variante porte un statut HTTP
et un code lisible par machine :
| Variante | Statut | Code |
|---|---|---|
InvalidInput | 400 | INVALID_INPUT |
Validation | 400 | VALIDATION_FAILED |
Unauthorized | 401 | UNAUTHORIZED |
Forbidden | 403 | FORBIDDEN |
NotFound | 404 | NOT_FOUND |
Conflict | 409 | CONFLICT |
Unprocessable | 422 | UNPROCESSABLE |
RateLimited | 429 | RATE_LIMITED |
Internal, Config, Serialization | 500 | INTERNAL_ERROR, CONFIG_ERROR, SERIALIZATION_ERROR |
Database | 500 | DATABASE_ERROR |
Vault | 500 | VAULT_ERROR |
Upstream | 502 | UPSTREAM_ERROR |
CircuitOpen, Unavailable | 503 | CIRCUIT_OPEN, SERVICE_UNAVAILABLE |
Timeout | 504 | TIMEOUT |
Vault et VAULT_ERROR sont des noms historiques du code : le coffre de
secrets du produit est OpenBao.
Les erreurs de domaine (Agent, Workflow, Rag, Embedding,
HallucinationDetected, Ollama) répondent 500 avec les codes
AGENT_ERROR, WORKFLOW_ERROR, RAG_ERROR, EMBEDDING_ERROR,
HALLUCINATION_DETECTED et OLLAMA_ERROR.
Le corps de réponse a toujours la même forme :
{
"error": {
"code": "NOT_FOUND",
"message": "resource not found: user id=42",
"status": 404
}
}
Une réponse 429 ajoute le champ retryAfterSecs dans le corps et
l'en-tête HTTP Retry-After. La conversion en réponse HTTP est faite
par crates/forge-common/src/error.rs : niveau de trace warn pour un
404, info pour les autres 4xx, error pour les 5xx.
Pour agir sur un code précis (TIMEOUT, SERVICE_UNAVAILABLE, RATE_LIMITED,
CIRCUIT_OPEN, session MCP expirée), voir Problèmes connus.
Messages sans fuite d'information
Un message d'erreur de base de données, de client HTTP ou de fichier peut
embarquer une requête SQL, une URL interne ou un chemin local. Les
handlers passent donc par safe_message
(crates/forge-api/src/safe_error.rs) : le client reçoit un texte fixe
et neutre. En développement local seulement, l'opérateur peut démarrer
le serveur avec FORGE_VERBOSE_ERRORS=1 pour obtenir le détail.
Le même module fournit error_body et error_body_with_request_id
(ajoute un champ request_id pour relier une réponse à ses traces).
Transport MCP
Le transport Streamable HTTP répond en JSON-RPC 2.0. Codes émis par
crates/forge-mcp/src/transport/ et crates/forge-api/src/routes/mcp.rs :
| Code | Cas | Exemple de message |
|---|---|---|
| -32700 | JSON invalide | invalid JSON-RPC request |
| -32600 | Requête invalide | missing Mcp-Session-Id, session expired or unknown |
| -32601 | Méthode inconnue | method '<nom>' not found |
| -32602 | Paramètres invalides | missing 'name' |
| -32603 | Erreur interne | tool call failed, session creation failed |
Les messages du code -32603 sont génériques (passés par safe_message).
Une session expire après 30 minutes d'inactivité : le client doit alors
renvoyer initialize.
Connecteurs
- Limite amont atteinte : si le service tiers répond 429, le
connecteur renvoie
RATE_LIMITEDavec leRetry-Afterde l'amont (60 secondes à défaut). Un connecteur peut aussi déclarerrate_limit_per_min: la limite est alors vérifiée avant l'appel réseau. - Délai dépassé : chaque connecteur a un
timeout_ms(30 000 par défaut). Un dépassement est renvoyé enTIMEOUT(504). - Service injoignable : une erreur de connexion devient
SERVICE_UNAVAILABLE(503). - URL interdite : une URL de base fournie par un locataire qui vise
le réseau interne est refusée avant tout appel (
Forbidden, messageSSRF_BLOCKED).
Agents : disjoncteur
Chaque agent exécuté par un AgentWorker
(crates/forge-core/src/agent/worker.rs) est protégé par un disjoncteur
à trois états (fermé, ouvert, semi-ouvert). Par défaut il s'ouvre après
quelques échecs consécutifs, reste ouvert un court délai avant de passer en
semi-ouvert, et considère un appel comme échoué au-delà d'un délai borné.
Tant qu'il est ouvert, l'appel échoue immédiatement avec CIRCUIT_OPEN
(503). Une primitive générique équivalente existe dans
crates/forge-core/src/security/circuit_breaker.rs.
Moteur d'IA : dégradation par paliers
Cette cascade est livrée mais non branchée : les moteurs de raisonnement
qu'elle coupe n'ont pas d'appelant de production (voir
Supervision). Le moniteur de ressources du moteur MGaaS
(crates/forge-core/src/mgaas/resource_monitor.rs) choisit un niveau de
dégradation à partir de la RAM utilisée, du CPU et de la latence moyenne.
Il existe cinq niveaux, par ordre décroissant de capacités :
FULL: toutes les techniques de raisonnement actives ;NO_MCTS: MCTSLite désactivé ;NO_TOT: ToTLite désactivé en plus ;NO_SELF_CONSISTENCY: l'auto-cohérence est désactivée en plus ;TEMPLATE_ONLY: réponses issues de gabarits, dernier recours.
Les seuils (mémoire, processeur, latence) sont fixés dans le code du moniteur de ressources et ne sont pas publiés ici.
Règle appliquée : si un seul seuil critique est franchi, le niveau est
TEMPLATE_ONLY. Sinon, si un seuil d'avertissement est franchi, le niveau
est NO_SELF_CONSISTENCY quand la mémoire dépasse nettement son seuil
d'avertissement, NO_TOT quand le processeur est très chargé, et NO_MCTS dans les
autres cas, latence comprise (marges fixées dans le code).
Figure 2 : les cinq niveaux de dégradation du moteur d'IA, par ordre décroissant de capacités.
Le moteur anti-hallucination (crates/forge-core/src/anti_hallucination/)
a son propre indicateur de niveau opérationnel, distinct du précédent :
Full, NoCache, NoRag, NoSemantic, TemplateOnly, Maintenance.
Il décide quelles fonctions sont annoncées au client, et ne se confond
pas avec le moniteur de ressources ci-dessus.
Observabilité
- Les journaux du backend sont écrits en JSON par défaut ;
LOG_FORMAT=prettyoucompactdonne une sortie lisible (init_tracing,crates/forge-api/src/main.rs).TRACING_JSON, fixée danspodman-compose.yml, n'est pas lue parforge-api. - Chaque requête reçoit un identifiant par la couche
RequestIdLayer. - Le plan backend embarque VictoriaMetrics (métriques) et VictoriaLogs (logs) ; la détection d'intrusion repose sur CrowdSec. L'unité Falco existe mais est retirée du déploiement depuis le 2026-09-19.
Voir aussi
- Architecture Chatbotaurus : où vivent les couches qui produisent ces erreurs
- Conception des connecteurs MCP : délai, limite amont et contrôle SSRF déclarés côté connecteur
- Problèmes connus : session expirée, connecteur en échec, disjoncteur ouvert : que faire
- Documentation Swagger : contrat OpenAPI et authentification : format des erreurs et limites de débit vus du client
- Supervision : état réel de la cascade de dégradation et des métriques exposées