Răsfoiți Sursa

Erreurs de l'API : message selon la vraie cause

Une requête refusée (400) n'est plus toujours présentée comme un
problème de formulation, ou d'image dès qu'une image est jointe. Le
texte de l'erreur est lu : image refusée, conversation trop longue
(/reset proposé), ou configuration (réglage du .env, crédit épuisé),
pour laquelle Rika demande de prévenir l'administrateur. Un modèle
introuvable (404) ou un accès refusé (403) sont aussi traités comme
des erreurs de configuration, avec la cause dans les logs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Johnounet 4 zile în urmă
părinte
comite
0108398e0b
2 a modificat fișierele cu 39 adăugiri și 4 ștergeri
  1. 32 4
      bot/claude_client.py
  2. 7 0
      changelog.txt

+ 32 - 4
bot/claude_client.py

@@ -95,6 +95,9 @@ CUSTOM_STATUS_PROMPT = (
 
 CUSTOM_EMOJI = re.compile(r"<a?:\w+:\d+>")
 
+# Erreur due à la configuration (clé, crédit, modèle, réglages) : seul l'administrateur peut la corriger.
+CONFIG_ERROR = "Je suis mal configuré, préviens l'administrateur du bot."
+
 # Nombre maximal de relances quand l'API met la réponse en pause pendant les recherches.
 MAX_CONTINUATIONS = 3
 
@@ -284,17 +287,42 @@ class ClaudeClient:
             logger.error("Connexion à l'API impossible : %s", exc)
             raise ClaudeError("Je n'arrive pas à joindre mon cerveau pour l'instant, réessaie plus tard.")
         except anthropic.BadRequestError as exc:
-            logger.error("Requête refusée par l'API : %s", exc)
-            if has_image:
+            # Toutes les erreurs 400 ont le même type : seul le texte de l'API en donne la cause.
+            message = self._api_message(exc).lower()
+            if has_image and "image" in message:
+                logger.error("Image refusée par l'API : %s", exc)
                 raise ClaudeError("Je n'ai pas réussi à lire cette image, essaie avec une autre.")
-            raise ClaudeError("Ta demande a été refusée par l'API, essaie de la reformuler.")
+            if "prompt is too long" in message:
+                logger.error("Requête trop longue pour le modèle : %s", exc)
+                raise ClaudeError("Ce message est trop long pour moi avec la conversation en cours. "
+                                  "Un modérateur peut vider ma mémoire avec /reset.")
+            if "credit balance" in message:
+                logger.critical("Crédit Anthropic épuisé : %s", exc)
+                raise ClaudeError(CONFIG_ERROR)
+            logger.critical("Requête refusée par l'API, sans doute à cause d'un réglage du .env "
+                            "(MODEL, MAX_TOKENS, THINKING, EFFORT, WEB_SEARCH…) : %s", exc)
+            raise ClaudeError(CONFIG_ERROR)
         except anthropic.AuthenticationError:
             logger.critical("Clé API Anthropic invalide : vérifie ANTHROPIC_API_KEY dans le .env.")
-            raise ClaudeError("Je suis mal configuré, préviens l'administrateur du bot.")
+            raise ClaudeError(CONFIG_ERROR)
+        except anthropic.PermissionDeniedError as exc:
+            logger.critical("Accès refusé par l'API (clé sans accès à ce modèle ou à cet outil ?) : %s", exc)
+            raise ClaudeError(CONFIG_ERROR)
+        except anthropic.NotFoundError as exc:
+            logger.critical("Modèle introuvable : vérifie MODEL dans le .env (%s).", exc)
+            raise ClaudeError(CONFIG_ERROR)
         except anthropic.APIStatusError as exc:
             logger.error("Erreur de l'API (%s) : %s", exc.status_code, exc)
             raise ClaudeError("Une erreur est survenue de mon côté, réessaie dans un instant.")
 
+    @staticmethod
+    def _api_message(exc: anthropic.APIStatusError) -> str:
+        """Texte de l'erreur renvoyée par l'API ({"error": {"message": …}})."""
+        body = exc.body
+        if isinstance(body, dict) and isinstance(body.get("error"), dict):
+            return str(body["error"].get("message", ""))
+        return str(exc)
+
     @staticmethod
     def _final_text(responses) -> str:
         """Texte de la réponse finale, sans les commentaires écrits entre deux recherches."""

+ 7 - 0
changelog.txt

@@ -17,6 +17,13 @@ Corrections
   converties en JPEG, qui brouillait le texte (le JPEG ne sert plus que si
   le PNG dépasse la limite de l'API). Les images en palette (PNG optimisés,
   GIF) sont réduites proprement, et non plus au plus proche voisin.
+- Erreurs de l'API : une requête refusée n'est plus toujours présentée
+  comme un problème de formulation (ou d'image dès qu'une image est
+  jointe). Rika parle de l'image seulement si c'est elle qui pose
+  problème, propose /reset si la conversation est trop longue, et demande
+  de prévenir l'administrateur pour un réglage du .env refusé, un crédit
+  épuisé, un modèle introuvable ou un accès refusé ; les logs en donnent
+  la cause.
 
 
 Version 5.6 — 30/10/2026