fix(http客户端): 增强超时错误处理并保留URL用于错误提示

在请求发送和响应体读取时添加明确的超时错误处理,使用clone保留URL以便在错误信息中显示
This commit is contained in:
2025-10-09 23:31:00 +08:00
parent 446f63e02a
commit a4d20bc788

View File

@ -49,7 +49,8 @@ pub async fn execute_http(req: HttpRequest, opts: HttpClientOptions) -> Result<H
let client = builder.build()?; let client = builder.build()?;
// Build request // Build request
let mut rb = client.request(req.method.parse()?, req.url); // 使用 clone 保留 url 以便在错误提示中引用
let mut rb = client.request(req.method.parse()?, req.url.clone());
// Also set per-request timeout to ensure it takes effect in all cases // Also set per-request timeout to ensure it takes effect in all cases
if let Some(ms) = opts.timeout_ms { if let Some(ms) = opts.timeout_ms {
@ -85,7 +86,20 @@ pub async fn execute_http(req: HttpRequest, opts: HttpClientOptions) -> Result<H
rb = rb.json(&b); rb = rb.json(&b);
} }
let resp = rb.send().await?; // 发送请求,明确标注超时错误
let resp = match rb.send().await {
Ok(r) => r,
Err(e) => {
if e.is_timeout() {
let hint = match opts.timeout_ms {
Some(ms) => format!("http timeout: request {} timed out after {}ms", req.url, ms),
None => format!("http timeout: request {} timed out", req.url),
};
return Err(anyhow::Error::new(e).context(hint));
}
return Err(e.into());
}
};
let status = resp.status().as_u16(); let status = resp.status().as_u16();
let headers_out: Map<String, Value> = resp let headers_out: Map<String, Value> = resp
.headers() .headers()
@ -93,7 +107,20 @@ pub async fn execute_http(req: HttpRequest, opts: HttpClientOptions) -> Result<H
.map(|(k, v)| (k.to_string(), Value::String(v.to_str().unwrap_or("").to_string()))) .map(|(k, v)| (k.to_string(), Value::String(v.to_str().unwrap_or("").to_string())))
.collect(); .collect();
let text = resp.text().await?; // 读取响应体,明确标注超时错误
let text = match resp.text().await {
Ok(t) => t,
Err(e) => {
if e.is_timeout() {
let hint = match opts.timeout_ms {
Some(ms) => format!("http timeout: reading body from {} timed out after {}ms", req.url, ms),
None => format!("http timeout: reading body from {} timed out", req.url),
};
return Err(anyhow::Error::new(e).context(hint));
}
return Err(e.into());
}
};
let parsed_body: Value = serde_json::from_str(&text).unwrap_or_else(|_| Value::String(text)); let parsed_body: Value = serde_json::from_str(&text).unwrap_or_else(|_| Value::String(text));
Ok(HttpResponse { Ok(HttpResponse {