英文:
Reqwest: read body text and return 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(())
}
英文:
I want to use reqwest to make a request, then print the response's body and return a reqwest::Error if the status code was >= 400. This is how I would like to do this:
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(())
The trouble is that both response.text()
and response.error_for_status()
consume the response. Debug printing the response itself or the error from response.error_for_status()
does not print the response body.
I've tried saving the status code, then generating a reqwest::Error if the status code is >= 400, but reqwest::Error is not meant to be constructed by library users since its inner
field and constructor are private. Ideally a reqwest::Error is returned since other functions depend on this API, and I would like to understand if it's possible to achieve this without changing the public interface.
答案1
得分: 2
你可能忽略了error_for_status_ref()
方法,它不会消耗响应。只需要交换调用的顺序:
pub async fn print_body() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://www.rust-lang.org").await?;
response.error_for_status_ref()?;
println!("received text: {:?}", response.text().await?);
Ok(())
}
要始终打印文本,只需存储error_for_status_ref()
的结果,并将引用映射到Ok
情况,使其为()
,以匹配函数的返回类型:
pub async fn print_body() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://www.rust-lang.org").await?;
let result = response.error_for_status_ref().map(|_| ());
println!("received text: {:?}", response.text().await?);
result
}
英文:
You might have glossed over the error_for_status_ref()
method, which does not consume the response. You just need to swap the order of the calls:
pub async fn print_body() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://www.rust-lang.org").await?;
response.error_for_status_ref()?;
println!("received text: {:?}", response.text().await?);
Ok(())
}
To print the text regardless, just store the result of error_for_status_ref()
and map the reference in the Ok
case to be ()
to match the return type of your function:
pub async fn print_body() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://www.rust-lang.org").await?;
let result = response.error_for_status_ref().map(|_| ());
println!("received text: {:?}", response.text().await?);
result
}
答案2
得分: 2
没有问题,如果你在检索文本之前处理了错误情况,因为error_for_status
在一切正常时返回Response
:
pub async fn print_body() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://www.rust-lang.org").await?;
println!("received text: {:?}", response.error_for_status()?.text().await?);
Ok(())
}
英文:
There is no issue if you handle your error case before you retreive the text as error_for_status
returns the Response
if everything is ok:
pub async fn print_body() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://www.rust-lang.org").await?;
println!("received text: {:?}", response.error_for_status()?.text().await?);
Ok(())
}
答案3
得分: 0
谢谢 @cafce25 指出 error_for_status_ref
,我最初忽略了它,因为它在 Ok() 时返回对 self 的引用,如果我试图在调用 .text()
后保留完整的结果以供使用,将会给我编译器错误。但使用 .err()
仅提取错误部分可以解决此问题:
pub async fn print_body() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://www.rust-lang.org").await?;
let maybe_err = response.error_for_status_ref().err();
println!("received text: {:?}", response.text().await?);
match maybe_err {
Some(e) => Err(e),
None => Ok(()),
}
}
英文:
Thank you, @cafce25 for pointing me back to error_for_status_ref
, which I originally passed over since it returns a reference to self on Ok(), giving me compiler errors if I tried to keep the full result to use after calling .text()
. But grabbing just the error with .err()
resolves it:
pub async fn print_body() -> Result<(), reqwest::Error> {
let response = reqwest::get("https://www.rust-lang.org").await?;
let maybe_err = response.error_for_status_ref().err();
println!("received text: {:?}", response.text().await?);
match maybe_err {
Some(e) => Err(e),
None => Ok(()),
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论