12

I am very new to rust and I want to write a script to scrape a page and pull all the links from it with their titles. I have failed to even make the get request. :(

fn main() {
    println!("Started!");
    let body = reqwest::get("https://news.ycombinator.com")
    .await?
    .text()
    .await?;

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

I am clearly not returning anything however I am confused with the syntax can someone explain the ? operator and also help me fix this issue.

Liam Seskis
  • 161
  • 1
  • 2
  • 10
  • 1
    https://doc.rust-lang.org/std/result/#the-question-mark-operator- – Sergio Tulentsev Oct 14 '19 at 09:22
  • https://rust-lang.github.io/async-book/07_workarounds/03_err_in_async_blocks.html – Sergio Tulentsev Oct 14 '19 at 09:25
  • Also see: [Strange error: cannot use the `?` operator in a function that returns `()`](https://stackoverflow.com/questions/52225498/strange-error-cannot-use-the-operator-in-a-function-that-returns) and [Cannot use `?` operator for functions that return Result<(), error>](https://stackoverflow.com/questions/48015600/cannot-use-operator-for-functions-that-return-result-error) for more answers. – trent Oct 14 '19 at 12:20

1 Answers1

15

The question mark operator can only be used inside functions that return a std::Result. Roughly speaking, you can think of x? as meaning

match x {
    Err(e) => return Err(e),
    Ok(y) => y,
}

(see documentation here)

What do you want to happen when await produces an error result? If you're not expecting an error to ever occur, then it should be safe to tell Rust to panic (i.e. crash) if it does. This is what Result::unwrap is for:

fn main() {
    println!("Started!");
    let body = reqwest::get("https://news.ycombinator.com")
        .await
        .unwrap()
        .text()
        .await
        .unwrap();

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

More likely, you should handle error results responsibly with some well defined behaviour. This could be attempting to recover (i.e. trying something different), or maybe logging an error message and exiting with a non-zero code if you're in the top-level main function. The simple way to do either of these would be to use a match statement yourself.

From this perspective, it becomes clear what the intent of the ? operator is: it's a way of saying "It's not my responsibility to handle this error – it's the responsibility of the code that called me." The important thing here is that it still has to be someone's responsibility to decide how to handle errors.

user31601
  • 2,482
  • 1
  • 12
  • 22