feat: typed ApiStatusError carrying HTTP status through LLM client errors

catch_error and sse_stream now bail with ApiStatusError{status, message}
instead of bare anyhow strings, preserving every existing Display output
byte-for-byte. Enables structural status classification (e.g. 401
detection) via downcast through anyhow context chains.
This commit is contained in:
2026-08-14 13:01:08 -06:00
parent e1604c58ea
commit f3d59ade11
2 changed files with 141 additions and 14 deletions
+10 -6
View File
@@ -1,4 +1,4 @@
use super::{ThinkingBlock, ToolCall, catch_error};
use super::{ApiStatusError, ThinkingBlock, ToolCall, catch_error};
use crate::utils::AbortSignal;
use anyhow::{Context, Result, anyhow, bail};
@@ -224,10 +224,14 @@ where
let data: Value = match text.parse() {
Ok(data) => data,
Err(_) => {
bail!(
"Invalid response data: {text} (status: {})",
status.as_u16()
);
return Err(ApiStatusError {
status: status.as_u16(),
message: format!(
"Invalid response data: {text} (status: {})",
status.as_u16()
),
}
.into());
}
};
catch_error(&data, status.as_u16())?;
@@ -465,4 +469,4 @@ mod tests {
{"key": "value3"}"#;
assert_json_stream!(input, output);
}
}
}