How to solve this return error?

I'm creating an application to get data from an API. Then I used reqwest. Main.rs file has server configuration. Then I created route.rs file to manage every methods. And I created separated files to each function.

route.rs

use crate::search::User;
use actix_web::{get, post, put, delete, web, HttpResponse, Responder};
use serde_json::json;
extern crate reqwest;
extern crate serde;
mod common;

#[get("/token")]
async fn get_token() -> String {
    let set_token = common::authenticate(); 
    return set_token;
}

common.rs

extern crate reqwest;
use hyper::header::{Headers, Authorization, Basic, ContentType};

pub fn authenticate() -> Result<(), reqwest::Error> {
       return get_page();
}

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

    fn construct_headers() -> Headers {
        let mut headers = Headers::new();
        headers.set(
            Authorization(
                Basic {
                    username: "HI:ATYHNJ".to_owned(),
                    password: Some("987654".to_owned())
                }
            )
         );
        headers.set(ContentType::form_url_encoded());
        headers
    }

    let client = reqwest::Client::new();
    let reszr = client.post("https://api.test.com/auth/token")
    .headers(construct_headers())
    .body("grant_type=client_credentials")
        .send()
        .await?
        .text()
        .await?;

    Ok(reszr)
}

When I build it, it gives me these below errors.

Compiling sabre-actix-kist v0.1.0 (E:\wamp64\www\BukFlightsNewLevel\flights\APIs\sabre-actix-kist)
[Running 'cargo run']==============================================> ] 282/283: sabre-actix-kist(bin)
   Compiling sabre-actix-kist v0.1.0 (E:\wamp64\www\BukFlightsNewLevel\flights\APIs\sabre-actix-kist)
error[E0308]: mismatched types
  --> src\search\routes.rs:23:12
   |
23 |     return set_token;
   |            ^^^^^^^^^ expected struct `std::string::String`, found enum `std::result::Result`
   |
   = note: expected struct `std::string::String`
                found enum `std::result::Result<(), search::routes::reqwest::Error>`

error[E0277]: the trait bound `std::result::Result<search::routes::reqwest::Response, search::routes::reqwest::Error>: std::future::Future` is not satisfied
  --> src\search\routes\common.rs:26:17
   |
26 |       let reszr = client.post("https://api-crt.cert.havail.sabre.com/v2/auth/token")
   |  _________________^
27 | |     .headers(construct_headers())
28 | |     .body("grant_type=client_credentials")
29 | |         .send()
30 | |         .await?
   | |______________^ the trait `std::future::Future` is not implemented for `std::result::Result<search::routes::reqwest::Response, search::routes::reqwest::Error>`

How can I fix this ??

For the first error, please read this chapter. As for the second, which version of reqwest are you using?

2 Likes

I didn't understand this. Can u please explain little bit ?? I am using version 0.8.8.

For the first error, it's really a bit more complicated. The problem is in the error message: since we're dealing with async function, it should be read inversely - "expected Result (due to return value), got String (which is really being returned)".

Then what should I do to get response to route.rs ??

You need to use reqwest version 0.10 to use async await with reqwest.

When I use it in the Cargo.toml and start to run, terminal shows this -

" Blocking waiting for file lock on package cache "

I cna't use 0.10 version.

Just wait a bit longer. It's your IDEs code completion that's busy doing some work that its waiting for.

1 Like

And what should I use as return types in both functions ??

The return type should be the kind of data you want to return.

It still gives me these errors.

error[E0277]: the trait bound `search::routes::reqwest::Error: search::routes::serde::Serialize` is not satisfied
  --> src\search\routes.rs:24:29
   |
24 |     HttpResponse::Ok().json(set_token)
   |                             ^^^^^^^^^ the trait `search::routes::serde::Serialize` is not implemented for `search::routes::reqwest::Error`
   |
   = note: required because of the requirements on the impl of `search::routes::serde::Serialize` for `std::result::Result<(), search::routes::reqwest::Error>`

error[E0308]: mismatched types
  --> src\search\routes\common.rs:27:14
   |
27 |     .headers(construct_headers())
   |              ^^^^^^^^^^^^^^^^^^^ expected struct `search::routes::reqwest::header::HeaderMap`, found struct `hyper::header::Headers`
   |
   = note: expected struct `search::routes::reqwest::header::HeaderMap`
              found struct `hyper::header::Headers`

error[E0308]: mismatched types
  --> src\search\routes\common.rs:34:8
   |
34 |     Ok(reszr)
   |        ^^^^^ expected `()`, found struct `std::string::String`

The set_token variable is a Result. You need to handle errors first.

And what about 27 & 34 ?? And how can I handle this error ?? I dont understand..

For 27 you have a HeaderMap, but you need to convert it into a Headers. I'm not quite sure what the best way to do that is, but you should probably look at the documentation of the two mentioned types.

For 34 it appears that you're trying to return a String, but that's not the right return type.

I tried lots of ways. But, still I couldn't get the response. Each and every step gives me an error. Can u please demonstrate little bit ??

If a function returns Result<...>, you can use .unwrap() to get the inner value out. This will kill your program if the operation failed.

1 Like

Now I have changed my code like below. And I am using version 0.10 of reqwest.

extern crate reqwest;
use hyper::header::{Headers, Authorization, Basic, ContentType};

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

return get_page();
}

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

    fn construct_headers() -> Headers {
        let mut headers = Headers::new();
        headers.set(
            Authorization(
                Basic {
                    username: "GT:GTHYN".to_owned(),
                    password: Some("ABGHT".to_owned())
                }
            )
         );
        headers.set(ContentType::form_url_encoded());
        headers
    }

    let client = reqwest::Client::new();
    let reszr = client.post("https://api.test.com/auth/token")
    .headers(construct_headers())
    .body("grant_type=client_credentials")
        .send()
        .await?
        .text()
        .await?;
        
return reszr;
}

And it gives me these errors.

error[E0308]: mismatched types
  --> src\search\routes\common.rs:27:14
   |
27 |     .headers(construct_headers())
   |              ^^^^^^^^^^^^^^^^^^^ expected struct `search::routes::reqwest::header::HeaderMap`, found struct `hyper::header::Headers`
   |
   = note: expected struct `search::routes::reqwest::header::HeaderMap`
              found struct `hyper::header::Headers`

error[E0308]: mismatched types
  --> src\search\routes\common.rs:34:12
   |
34 |     return reszr;
   |            ^^^^^ expected enum `std::result::Result`, found struct `std::string::String`
   |
   = note: expected type `std::result::Result<(), search::routes::reqwest::Error>`
            found struct `std::string::String`

You are mixing the hyper and reqwest crates with the headers. Please change your code to use HeaderMap instead. As for the reszr error, it's because you need to return Ok(reszr).

I changed as you said. But its not working.

Sorry, I can't guess the error you got.