handle agent error better

if agent filter return 4xx, properly cascade the error text back to the developer

this code change will help build agent filters and allow them to early terminate if for example intent deviates or jailbreak attempt is made
This commit is contained in:
Adil Hafeez 2025-12-09 15:12:40 -08:00
parent 09c0b999b2
commit 4e0c785cd2
2 changed files with 66 additions and 1 deletions

View file

@ -37,7 +37,38 @@ pub async fn agent_chat(
match handle_agent_chat(request, router_service, agents_list, listeners).await {
Ok(response) => Ok(response),
Err(err) => {
// Print detailed error information with full error chain
// Check if this is a client error from the pipeline that should be cascaded
if let AgentFilterChainError::Pipeline(PipelineError::ClientError {
agent,
status,
body,
}) = &err
{
warn!(
"Client error from agent '{}' (HTTP {}): {}",
agent, status, body
);
// Create error response with the original status code and body
let error_json = serde_json::json!({
"error": "ClientError",
"agent": agent,
"status": status,
"agent_response": body
});
let json_string = error_json.to_string();
let mut response = Response::new(ResponseHandler::create_full_body(json_string));
*response.status_mut() =
hyper::StatusCode::from_u16(*status).unwrap_or(hyper::StatusCode::BAD_REQUEST);
response.headers_mut().insert(
hyper::header::CONTENT_TYPE,
"application/json".parse().unwrap(),
);
return Ok(response);
}
// Print detailed error information with full error chain for other errors
let mut error_chain = Vec::new();
let mut current_error: &dyn std::error::Error = &err;

View file

@ -19,6 +19,18 @@ pub enum PipelineError {
NoChoicesInResponse(String),
#[error("No content in response from agent '{0}'")]
NoContentInResponse(String),
#[error("Client error from agent '{agent}' (HTTP {status}): {body}")]
ClientError {
agent: String,
status: u16,
body: String,
},
#[error("Server error from agent '{agent}' (HTTP {status}): {body}")]
ServerError {
agent: String,
status: u16,
body: String,
},
}
/// Service for processing agent pipelines
@ -122,8 +134,30 @@ impl PipelineProcessor {
.send()
.await?;
let status = response.status();
let response_bytes = response.bytes().await?;
// Check for HTTP errors and handle them appropriately
if !status.is_success() {
let error_body = String::from_utf8_lossy(&response_bytes).to_string();
if status.is_client_error() {
// 4xx errors - cascade back to developer
return Err(PipelineError::ClientError {
agent: agent.id.clone(),
status: status.as_u16(),
body: error_body,
});
} else if status.is_server_error() {
// 5xx errors - server/agent error
return Err(PipelineError::ServerError {
agent: agent.id.clone(),
status: status.as_u16(),
body: error_body,
});
}
}
// Parse the response as JSON to extract the content
let response_json: serde_json::Value = serde_json::from_slice(&response_bytes)?;