如何使用reqwest读取响应体后返回reqwest::Error(状态码≥400时)
问题
需要借助reqwest发起网络请求,打印响应体内容,同时要求当响应状态码≥400时返回reqwest::Error。原代码中response.text()与response.error_for_status()都会消费响应对象,导致无法在状态码异常时获取包含响应体的错误;尝试自行构造reqwest::Error,但因该类型的内部字段及构造函数均为私有而无法实现,要求不修改公共接口完成需求。
原代码示例:
pub async fn print_body() -> Result<(), reqwest::Error> { let response = reqwest::get("https://www.rust-lang.org").await?; println!("received text: {:?}", response.text().await?); response.error_for_status()?; Ok(()) }
解决方案
方法一:先检状态码再处理响应体
利用reqwest::Response::error_for_status_ref方法——该方法不会消费响应对象,仅检查状态码并返回错误引用,这样就能在状态异常时读取响应体并附加到错误中:
pub async fn print_body() -> Result<(), reqwest::Error> { let response = reqwest::get("https://www.rust-lang.org").await?; // 先检查状态码,不消费响应 if let Err(mut err) = response.error_for_status_ref() { // 状态异常时读取响应体 let body = response.text().await?; // 将响应体附加到错误中 return Err(err.with_body(body.into())); } // 状态正常时读取并打印响应体 let body = response.text().await?; println!("received text: {:?}", body); Ok(()) }
方法二:先获取状态码再处理响应体
如果需要先打印响应体再检查状态,可先提取状态码(不消费响应),读取响应体后再根据状态码构造包含响应体的错误:
pub async fn print_body() -> Result<(), reqwest::Error> { let response = reqwest::get("https://www.rust-lang.org").await?; // 提取状态码,不消费响应 let status = response.status(); // 读取并打印响应体 let body = response.text().await?; println!("received text: {:?}", body); // 检查状态码是否为错误码 if status.is_client_error() || status.is_server_error() { // 构造状态码错误并附加响应体 let mut err = reqwest::Error::new(reqwest::error::ErrorKind::Status, status.to_string()); err = err.with_body(body.into()); return Err(err); } Ok(()) }
关键说明
error_for_status_ref是reqwest提供的非消费式状态检查方法,完美解决了响应被提前消费的问题。reqwest::Error::with_body是公开方法,可将响应体附加到错误对象中,满足“返回包含响应体的错误”的需求,无需依赖私有构造函数或字段。
内容的提问来源于stack exchange,提问作者reqingball
相关产品推荐
相关产品推荐

