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.
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
}