mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-10 01:54:49 +08:00
fix(api): surface provider error in SSE stream frames (companion to ff416ff)
Same fix asff416ffbut for the streaming path. Some backends embed an error JSON object in an SSE data: frame: data: {"error":{"message":"context too long","code":400}} parse_sse_frame() was attempting to deserialize this as ChatCompletionChunk and failing with 'missing field' / 'invalid type', hiding the actual backend error message. Fix: check for an 'error' key before full chunk deserialization, same as the non-streaming path inff416ff. Symmetric pair: -ff416ff: non-streaming path (response body) - this: streaming path (SSE data: frame) 115 api + 159 CLI tests pass. Fmt clean.
This commit is contained in:
@@ -1084,6 +1084,35 @@ fn parse_sse_frame(
|
||||
if payload == "[DONE]" {
|
||||
return Ok(None);
|
||||
}
|
||||
// Some backends embed an error object in a data: frame instead of using an
|
||||
// HTTP error status. Surface the error message directly rather than letting
|
||||
// ChatCompletionChunk deserialization fail with a cryptic 'missing field' error.
|
||||
if let Ok(raw) = serde_json::from_str::<serde_json::Value>(&payload) {
|
||||
if let Some(err_obj) = raw.get("error") {
|
||||
let msg = err_obj
|
||||
.get("message")
|
||||
.and_then(|m| m.as_str())
|
||||
.unwrap_or("provider returned an error in stream")
|
||||
.to_string();
|
||||
let code = err_obj
|
||||
.get("code")
|
||||
.and_then(|c| c.as_u64())
|
||||
.map(|c| c as u16);
|
||||
let status = reqwest::StatusCode::from_u16(code.unwrap_or(400))
|
||||
.unwrap_or(reqwest::StatusCode::BAD_REQUEST);
|
||||
return Err(ApiError::Api {
|
||||
status,
|
||||
error_type: err_obj
|
||||
.get("type")
|
||||
.and_then(|t| t.as_str())
|
||||
.map(str::to_owned),
|
||||
message: Some(msg),
|
||||
request_id: None,
|
||||
body: payload.to_string(),
|
||||
retryable: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
serde_json::from_str::<ChatCompletionChunk>(&payload)
|
||||
.map(Some)
|
||||
.map_err(|error| ApiError::json_deserialize(provider, model, &payload, error))
|
||||
|
||||
Reference in New Issue
Block a user