Reqwest POST call gives client (connect) error before giving response. How to get more descriptive error?

Rust beginner here. I'm trying to make a post request using basic auth with reqwest.

This is my code
use std::error::Error;
use reqwest::Client;
use reqwest::Error as rError;
use futures::executor::block_on;

const URL_BASE: &str = "REDACTED";
const USERNAME: &str = "REDACTED";
const PASSWORD: &str = "REDACTED";

pub fn get_token() {
    let res = block_on(get_token_async());
    match res {
        Ok(_) => println!("Success"),
        Err(e) => {
            eprintln!("{}", e);
            if let Some(source) = e.source() {
                eprintln!("{}", source);
            }
        },
    }
}

pub async fn get_token_async() -> Result<(), rError> {
    let client = Client::new();
    let url = String::from(URL_BASE.to_owned() + "/uaa/oauth/token");
    let response = client
        .get(url)
        .basic_auth(USERNAME, Some(PASSWORD))
        .query(&[("grant_type", "client_credentials")])
        .send()
        .await?;
    println!("{}", response.status());
    let token = response.text().await?;
    println!("{}", token);
    Ok(())
}
Main function
mod modulename;

#[tokio::main]
async fn main() {
    modulename::get_token();
}
Cargo.toml
[package]
name = "hist_migr"
version = "0.1.0"
edition = "2021"

[dependencies]
futures = "0.3.30"
reqwest = {version = "0.12.5", features = ["json"]}
tokio = {version = "1.39.2", features = ["full"]}

When I run it I get:

error sending request for url (REDACTED/uaa/oauth/token?grant_type=client_credentials)
client error (Connect)

The same link copy and pasted from the error into a browser works fine, returning the expected data...

Is there any way to get a more detailed description than just "client error"? If I can't know why the error happened or get the status code, I have no way of troubleshooting (especially since it works fine elsewhere). I'd appreciate any advice or direction, because at this point I'm out of ideas... Thank you in advance.

You are deadlocking the tokio runtime. Call the async function directly:

mod modulename;

#[tokio::main]
async fn main() {
  let _ =  modulename::get_token_async().await;
}
2 Likes

Thanks so much for the reply. I changed my main function to this:

#[tokio::main]
async fn main() {
    let res = modulename::get_token_async().await;
    
    match res {
        Ok(_) => println!("Success"),
        Err(e) => {
            eprintln!("{}", e);
            if let Some(source) = e.source() {
                eprintln!("{}", source);
            }
        },
    }
}

But I still get the exact same error:

error sending request for url (...)
client error (Connect)

You might need to enable one of the TLS features on reqwest if you happen to be calling an endpoint that requires a secure connection.

1 Like

Docs say that default-tls is enabled by default, but I added features = ["json", "default-tls", "native-tls", "rustls-tls"]} anyways. Still the same error. Is that error really as descriptive as its going to be?

Debug output ("{:?}") may show more. Chasing .source() recursively may show more.

1 Like

Thank you so much! Putting ("{:?}") gives:

error sending request for url (REDACTED/uaa/oauth/token?grant_type=client_credentials)
hyper_util::client::legacy::Error(Connect, Ssl(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 167772294, library: "SSL routines", function: "tls_post_process_server_certificate", reason: "certificate verify failed", file: "../ssl/statem/statem_clnt.c", line: 1889 }]))) }, X509VerifyResult { code: 19, error: "self-signed certificate in certificate chain" }))

which is so much more helpful. Gives me something to work with.

Could you explain what ("{:?}") does? Was I just printing the first element of an array or something before?

Placeholders for string formatting are documented in std::fmt. The ? format prints whatever the value's implementation of Debug prints, and most errors have a Debug implementation that gives extensive detail of the error, whereas the Display implementation (used by the {} placeholder) may only give a high-level error message.

2 Likes

Ah, I see now. Thank you!

Still trying to wrap my head around this language...

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.