Legg til retry med backoff for Claude API-feil (500/529)
Maskinrommet prøver nå opptil 3 ganger med eksponentiell backoff (2, 4, 8 sek) ved 500/529-feil fra Anthropic. Etter alle forsøk vises en vennlig melding i chatten i stedet for rå feilmeldinger. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d4715831bf
commit
244da69110
1 changed files with 50 additions and 21 deletions
|
|
@ -155,35 +155,64 @@ Svar KUN med meldingsteksten.
|
|||
{conversation}--- Svar ---"#
|
||||
);
|
||||
|
||||
// Kall claude CLI direkte
|
||||
// Kall claude CLI med retry ved API-feil (500/529)
|
||||
let claude_path = std::env::var("CLAUDE_PATH").unwrap_or_else(|_| "claude".to_string());
|
||||
let project_dir = std::env::var("PROJECT_DIR").unwrap_or_else(|_| "/home/vegard/synops".to_string());
|
||||
|
||||
tracing::info!(prompt_len = prompt.len(), "Kaller claude CLI");
|
||||
|
||||
let output = tokio::process::Command::new(&claude_path)
|
||||
.arg("-p")
|
||||
.arg(&prompt)
|
||||
.arg("--output-format")
|
||||
.arg("json")
|
||||
.arg("--dangerously-skip-permissions")
|
||||
.env("CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC", "1")
|
||||
.current_dir(&project_dir)
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Kunne ikke starte claude: {e}"))?;
|
||||
let max_retries = 3u32;
|
||||
let mut response_text = String::new();
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
return Err(format!("claude feilet ({}): {}", output.status, &stderr[..stderr.len().min(500)]));
|
||||
for attempt in 0..=max_retries {
|
||||
let output = tokio::process::Command::new(&claude_path)
|
||||
.arg("-p")
|
||||
.arg(&prompt)
|
||||
.arg("--output-format")
|
||||
.arg("json")
|
||||
.arg("--dangerously-skip-permissions")
|
||||
.env("CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC", "1")
|
||||
.current_dir(&project_dir)
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("Kunne ikke starte claude: {e}"))?;
|
||||
|
||||
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
|
||||
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
|
||||
// Sjekk om dette er en retrybar API-feil (500/529)
|
||||
let is_api_error = !output.status.success()
|
||||
&& (stderr.contains("500") || stderr.contains("529")
|
||||
|| stderr.contains("overloaded") || stderr.contains("Internal Server Error"));
|
||||
|
||||
if is_api_error && attempt < max_retries {
|
||||
let delay = std::time::Duration::from_secs(2u64.pow(attempt + 1)); // 2, 4, 8 sek
|
||||
tracing::warn!(
|
||||
attempt = attempt + 1,
|
||||
delay_secs = delay.as_secs(),
|
||||
"Claude API-feil, prøver igjen"
|
||||
);
|
||||
tokio::time::sleep(delay).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
if !output.status.success() {
|
||||
if is_api_error {
|
||||
// Alle retries brukt opp — gi vennlig melding i stedet for rå feil
|
||||
tracing::error!(attempts = max_retries + 1, "Claude API utilgjengelig etter alle forsøk");
|
||||
response_text = "Beklager, jeg er midlertidig utilgjengelig — Anthropic sitt API svarer ikke akkurat nå. Prøv igjen om litt.".to_string();
|
||||
break;
|
||||
}
|
||||
return Err(format!("claude feilet ({}): {}", output.status, &stderr[..stderr.len().min(500)]));
|
||||
}
|
||||
|
||||
response_text = match serde_json::from_str::<serde_json::Value>(&stdout) {
|
||||
Ok(json) => json["result"].as_str().unwrap_or("").to_string(),
|
||||
Err(_) => stdout.trim().to_string(),
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
let response_text = match serde_json::from_str::<serde_json::Value>(&stdout) {
|
||||
Ok(json) => json["result"].as_str().unwrap_or("").to_string(),
|
||||
Err(_) => stdout.trim().to_string(),
|
||||
};
|
||||
|
||||
if response_text.is_empty() {
|
||||
return Err("Tom respons fra claude".to_string());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue