Block B: ClaudeCliError + differenzierte HTTP-Status + Rate-Limit-Retry
- Neue Exception-Klasse ClaudeCliError(error_type, message) in claude_client.py mit Kategorien rate_limit / auth_error / timeout / cli_error. - _classify_cli_error() als geteilter Klassifikator (Keywords fuer Rate-Limit und Auth-Fehler wie "does not have access", "login again"). - call_claude() erkennt jetzt auch is_error=true im JSON bei returncode=0 (Hauptursache des Ausfalls vom 22.04.: CLI liefert "Your organization does not have access" mit is_error=true statt Exit-Code). - Orchestrator: ClaudeCliError mit rate_limit/timeout als transient behandelt (3 Retries mit Backoff 0s/120s/300s). auth_error/cli_error brechen sofort ab ohne Retry. Behebt den bestehenden Bug, dass Rate-Limit-Fehler gar nicht retried wurden. - routers/incidents.py Enhance-Endpoint: ClaudeCliError wird auf 503 (auth_error) / 429 (rate_limit) gemappt, TimeoutError auf 504. - routers/chat.py _call_claude_chat(): wirft jetzt ClaudeCliError statt generischem RuntimeError. Chat-Endpoint mappt auth_error auf 503. - Frontend: neue ApiError-Klasse in api.js mit status+detail. generateDescription() in app.js zeigt differenzierte Toasts nach HTTP-Status (503/429/504/403). - dashboard.html: Cache-Bust api.js + app.js auf v=20260423a
Dieser Commit ist enthalten in:
@@ -1816,8 +1816,15 @@ async generateDescription() {
|
||||
textarea.value = result.description;
|
||||
_autoResizeTextarea(textarea);
|
||||
} catch (err) {
|
||||
if (err.name !== 'AbortError') {
|
||||
UI.showToast('Beschreibung konnte nicht generiert werden', 'error');
|
||||
if (err.name === 'AbortError') {
|
||||
// still
|
||||
} else {
|
||||
let msg = 'Beschreibung konnte nicht generiert werden';
|
||||
if (err.status === 503) msg = 'KI-Zugang aktuell nicht verfügbar. Bitte Administrator kontaktieren.';
|
||||
else if (err.status === 429) msg = 'KI ist gerade ausgelastet. Bitte kurz warten und erneut versuchen.';
|
||||
else if (err.status === 504) msg = 'KI antwortet gerade nicht. Bitte erneut versuchen.';
|
||||
else if (err.status === 403) msg = err.detail || 'Zugriff verweigert.';
|
||||
UI.showToast(msg, 'error');
|
||||
}
|
||||
} finally {
|
||||
btnText.textContent = 'Beschreibung generieren';
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren