Web request example

I am trying to follow the example to build a web request:

https://rust-lang-nursery.github.io/rust-cookbook/web/clients/requests.html

But I always got errors:

error[E0107]: wrong number of type arguments: expected 2, found 1
--> src/main.rs:7:14
|
7 | fn main() -> Result<()> {
| ^^^^^^^^^^ expected 2 type arguments

error: aborting due to previous error

For more information about this error, try rustc --explain E0107.
error: could not compile http_req.

To learn more, run the command again with --verbose.

I don't understand it because I did copy&paste from the example.

A common pattern is to define a type alias for Result that hides the error type. It seems like they are using the alias in reqwest, however the example in the book seems to be missing an import of this type alias.

I would recommend you add this type alias:

type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

Edit: You can view any hidden lines by pressing the arrows in the upper right of the example. They are using the error_chain crate to introduce the type alias, but for simplicity I would simply use a box like I did above.

1 Like

I would opt for this instead

type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;

That way you can still conveniently use other error types.

1 Like

Setting a default of T = () can also be convenient if you have a lot of functions that don't return anything on success. Then you can write things like:

fn main() -> Result { ... }
1 Like

After I added hidden lines, I got next error:

--> src/main.rs:51:1
|
| extern crate error_chain;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate

You need to add this to your Cargo.toml:

[dependencies]
error-chain = "0.12.2"

I think it is different use. "Error-chain" is other library.

Are you sure? Perhaps the mis-understanding is that Rust translates hyphens "-" in crate names to underscores "_" when referenced in the code.

1 Like

You are right!

Now:

> error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
>   --> src/main.rs:38:19
>    |
> 38 |     let mut res = reqwest::get("http://www.marca.es")?;
>    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
>    |
>    = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
>    = note: required by `std::ops::Try::into_result`
> 
> error[E0308]: mismatched types
>   --> src/main.rs:30:14
>    |
> 30 | fn main() -> Result<()> {
>    |    ----      ^^^^^^^^^^ expected enum `std::result::Result`, found `()`
>    |    |
>    |    implicitly returns `()` as its body has no tail or `return` expression
> ...
> 45 |     Ok(());
>    |           - help: consider removing this semicolon
>    |
>    = note:   expected enum `std::result::Result<(), Error>`
>            found unit type `()`

This is what you want to do.

1 Like

Yes, I did. I

error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
  --> src/main.rs:38:19
   |
38 |     let mut res = reqwest::get("http://www.marca.es")?;
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
   |
   = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
   = note: required by `std::ops::Try::into_result`

I recommend you read the error message. You can only use ? on values of type Result or Option depending on what your function returns. A future is neither of those.

Then, the example is wrong?

The example is using an old version of reqwest, although it looks like the version number listed on the page has been incorrectly updated to the latest version.

But fair enough that you are confused about the error then.

I am learning rust and following the examples to learn for this reason maybe I asking silly things.

Yeah, I had forgotten what the thread was originally about. I believe you need reqwest version 0.9 for the given example to compile.

1 Like

I was using reqwest version 0.10.4.

Yes, and in that version of reqwest, you should be using the blocking module:

let mut res = reqwest::blocking::get("http://www.marca.es")?;

Consider taking a look at the documentation of the blocking module.

The non-blocking part of reqwest 0.10 is meant to work with the async ecosystem, which you are currently not using.

I got it. Thank you all.