Skip to content

Commit 367f48b

Browse files
authored
handle agent error better (#627)
1 parent 09c0b99 commit 367f48b

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

crates/brightstaff/src/handlers/agent_chat_completions.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,38 @@ pub async fn agent_chat(
3737
match handle_agent_chat(request, router_service, agents_list, listeners).await {
3838
Ok(response) => Ok(response),
3939
Err(err) => {
40-
// Print detailed error information with full error chain
40+
// Check if this is a client error from the pipeline that should be cascaded
41+
if let AgentFilterChainError::Pipeline(PipelineError::ClientError {
42+
agent,
43+
status,
44+
body,
45+
}) = &err
46+
{
47+
warn!(
48+
"Client error from agent '{}' (HTTP {}): {}",
49+
agent, status, body
50+
);
51+
52+
// Create error response with the original status code and body
53+
let error_json = serde_json::json!({
54+
"error": "ClientError",
55+
"agent": agent,
56+
"status": status,
57+
"agent_response": body
58+
});
59+
60+
let json_string = error_json.to_string();
61+
let mut response = Response::new(ResponseHandler::create_full_body(json_string));
62+
*response.status_mut() = hyper::StatusCode::from_u16(*status)
63+
.unwrap_or(hyper::StatusCode::INTERNAL_SERVER_ERROR);
64+
response.headers_mut().insert(
65+
hyper::header::CONTENT_TYPE,
66+
"application/json".parse().unwrap(),
67+
);
68+
return Ok(response);
69+
}
70+
71+
// Print detailed error information with full error chain for other errors
4172
let mut error_chain = Vec::new();
4273
let mut current_error: &dyn std::error::Error = &err;
4374

crates/brightstaff/src/handlers/pipeline_processor.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ pub enum PipelineError {
1919
NoChoicesInResponse(String),
2020
#[error("No content in response from agent '{0}'")]
2121
NoContentInResponse(String),
22+
#[error("Client error from agent '{agent}' (HTTP {status}): {body}")]
23+
ClientError {
24+
agent: String,
25+
status: u16,
26+
body: String,
27+
},
28+
#[error("Server error from agent '{agent}' (HTTP {status}): {body}")]
29+
ServerError {
30+
agent: String,
31+
status: u16,
32+
body: String,
33+
},
2234
}
2335

2436
/// Service for processing agent pipelines
@@ -122,8 +134,30 @@ impl PipelineProcessor {
122134
.send()
123135
.await?;
124136

137+
let status = response.status();
125138
let response_bytes = response.bytes().await?;
126139

140+
// Check for HTTP errors and handle them appropriately
141+
if !status.is_success() {
142+
let error_body = String::from_utf8_lossy(&response_bytes).to_string();
143+
144+
if status.is_client_error() {
145+
// 4xx errors - cascade back to developer
146+
return Err(PipelineError::ClientError {
147+
agent: agent.id.clone(),
148+
status: status.as_u16(),
149+
body: error_body,
150+
});
151+
} else if status.is_server_error() {
152+
// 5xx errors - server/agent error
153+
return Err(PipelineError::ServerError {
154+
agent: agent.id.clone(),
155+
status: status.as_u16(),
156+
body: error_body,
157+
});
158+
}
159+
}
160+
127161
// Parse the response as JSON to extract the content
128162
let response_json: serde_json::Value = serde_json::from_slice(&response_bytes)?;
129163

0 commit comments

Comments
 (0)