Handle context size errors in API responses
When the endpoint returns a context size error, the request should not
be retried as it indicates the request is too large for the model's
context window.
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
diff --git a/src/api_client.rs b/src/api_client.rs
index 1a1f004..7dc4aa6 100644
--- a/src/api_client.rs
+++ b/src/api_client.rs
@@ -7,8 +7,9 @@
};
use crate::conflict_resolver::ConflictResolver;
use crate::prob;
-use anyhow::{Context, Result};
+use anyhow::{Context, Result, bail};
use reqwest::Certificate;
+use std::fmt;
use std::fs::File;
use std::io::Read;
use std::time::Duration;
@@ -31,6 +32,19 @@
pub duration: f64,
}
+#[derive(Debug)]
+pub enum ApiRequestError {
+ ExceedContextSize,
+}
+
+impl fmt::Display for ApiRequestError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ ApiRequestError::ExceedContextSize => write!(f, "Exceed context size"),
+ }
+ }
+}
+
macro_rules! get_context_field {
($endpoint_context:expr, $variant_context:expr, $field:ident, $default:expr) => {{
let endpoint_value = $endpoint_context
@@ -209,6 +223,18 @@
"Failed to parse JSON response"
})?;
+ // Check for context size error in OpenAI responses
+ if let Some(error) = json_response.get("error")
+ && let Some(error_type) = error.get("type").and_then(|v| v.as_str())
+ && error_type == "exceed_context_size_error"
+ {
+ log::warn!(
+ "Context size error for endpoint {}. Not retrying.",
+ self.endpoint.name
+ );
+ bail!(ApiRequestError::ExceedContextSize);
+ }
+
let content = json_response
.get("choices")
.and_then(|choices| choices.get(0))
@@ -327,6 +353,20 @@
"Failed to parse JSON response"
})?;
+ // Check for context size error in Anthropic responses
+ if let Some(error) = json_response.get("error")
+ && let Some(error_type) = error.get("type").and_then(|v| v.as_str())
+ && error_type == "invalid_request_error"
+ && let Some(message) = error.get("message").and_then(|v| v.as_str())
+ && message.contains("Request size exceeds model context window")
+ {
+ log::warn!(
+ "Context size error for endpoint {}. Not retrying.",
+ self.endpoint.name
+ );
+ bail!(ApiRequestError::ExceedContextSize);
+ }
+
let content = json_response
.get("content")
.and_then(|choices| choices.get(0))
@@ -618,6 +658,15 @@
return Ok(api_response);
}
Err(e) => {
+ if let Some(api_error) = e.downcast_ref::<ApiRequestError>() {
+ match api_error {
+ ApiRequestError::ExceedContextSize => {
+ // If it's a context size error, don't retry
+ self.apply_wait().await;
+ return Err(e);
+ }
+ }
+ }
self.apply_delay(&mut delay, max_delay, &e).await;
last_error = Some(e);
}