1

I'm trying to replicate an example from reqwest documentation. Here is the example:

let body = reqwest::get("https://www.rust-lang.org")?
.text()?;

After I have added the reqwest = "0.10.10" line in the file Cargo.toml, I add the following code in my main.rs file:

extern crate reqwest;

fn main() {
    let body = reqwest::get("https://www.rust-lang.org")?.text()?;
    println!("body = {:?}", body);
}

This code don't compile and returns the following error:

cannot use the `?` operator in a function that returns `()`

I'm a bit surprised with this behaviour since my code is almost ipsis litteris the documentation code.

I think that ? works only on Response objects, so I checked which object the get method is returning:

extern crate reqwest;

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

fn main() {
    let body = reqwest::get("https://www.rust-lang.org");
    print_type_of(&body);
}

output:

core::future::from_generator::GenFuture<reqwest::get<&str>::{{closure}}

I mean, why I'm not getting an Response object instead, just like the documentation?

Lucas
  • 1,166
  • 2
  • 14
  • 34
  • 1
    Does this answer your question? [Why do try!() and ? not compile when used in a function that doesn't return Option or Result?](https://stackoverflow.com/questions/30555477/why-do-try-and-not-compile-when-used-in-a-function-that-doesnt-return-opti) – loganfsmyth Jan 04 '21 at 01:46
  • Thanks. But no. It doesn't. I don't have issues with `?` operator. I want to understand why I am receiving an object other than what, according to the documentation, would be expected. – Lucas Jan 04 '21 at 01:52
  • The "cannot use the `?` operator in a function that returns `()`" is because of this issue. `let body = reqwest::get("https://www.rust-lang.org")?.text()?;` is using a bunch of `?`, and the error is telling you that you are using `?` in a place where it isn't allowed, because `main` does not return a `Result`. – loganfsmyth Jan 04 '21 at 01:54
  • The documentation says that `get` should be of the type `pub fn get(url: T) -> Result`, while I'm getting `core::future::from_generator::GenFuture::{{closure}}`. The operator `?` would work perfectly if I was getting the right type of object instead. The problem is not `?` is the fact that `get` is not a response object in my case. – Lucas Jan 04 '21 at 02:01
  • You're right, there's actually two different problems, the one you mentioned and the one I did. – loganfsmyth Jan 04 '21 at 02:05

3 Answers3

3

There are two separate issues here tripping you up.

The documentation that you've linked to is for reqwest version 0.9.18, but you've installed version 0.10.10. If you look at the docs for 0.10.10, you will see that the snippet you use is

let body = reqwest::get("https://www.rust-lang.org")
    .await?
    .text()
    .await?;

println!("body = {:?}", body);

or more likely in your case, since you have not mentioned having an async runtime, the blocking docs

let body = reqwest::blocking::get("https://www.rust-lang.org")?
    .text()?;

println!("body = {:?}", body);

Note that when you try to use this one, you will still get that

cannot use the ? operator in a function that returns ()

and you will need to set a return type on main like

fn main() -> Result<(), reqwest::Error> {

See Why do try!() and ? not compile when used in a function that doesn't return Option or Result? for more info.

loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
1

You might want to read this section of the Rust docs: https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/index.html

In short, ? simply passes the error from a Result further up the call stack via an implicit return. As such the function in which you use the ? operator must return the same type as the function on which ? was used.

dbyr
  • 29
  • 4
0

Each response is wrapped in a Result type which you can unwrap.

use reqwest;
    
    #[tokio::main]
    async fn main() {
    
        let response = reqwest::get("https://www.rust-lang.org")
            .await
            .unwrap()
            .text()
            .await;
        println!("{:?}", response);
    }

Cargo.toml:

[package]
name = "request"
version = "0.1.0"
edition = "2021"
reqwest = "0.10.10"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
reqwest = { version = "0.11", features = ["json"] } # reqwest with JSON parsing support
futures = "0.3" # for our async / await blocks
tokio = { version = "1.12.0", features = ["full"] } # for async runtime
Olney1
  • 572
  • 5
  • 15