fix(http客户端): 增强超时错误处理并保留URL用于错误提示
在请求发送和响应体读取时添加明确的超时错误处理,使用clone保留URL以便在错误信息中显示
This commit is contained in:
@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user