roc-lang / basic-cli

A basic Command-Line Interface platform
Universal Permissive License v1.0
80 stars 26 forks source link

Request to specific API causes NetworkError on WSL #141

Open wric opened 9 months ago

wric commented 9 months ago

I have this minimal reproducing example with a basic GET to a specific API:

app "http-network-error"
    packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.7.0/bkGby8jb0tmZYsy2hg1E_B2QrCgcSTxdUlHtETwm5m4.tar.br" }
    imports [pf.Http, pf.Task.{ Task }, pf.Stdout]
    provides [main] to pf

main : Task {} I32
main =
    request = {
        method: Get,
        headers: [],
        url: "https://api-extern.systembolaget.se/site/V2/Search/Site",
        body: Http.emptyBody,
        timeout: NoTimeout,
    }

    output <- Http.send request
        |> Task.onErr \err -> err 
            |> Http.errorToString 
            |> Task.ok
        |> Task.await

    Stdout.line output

On Apple silicon it works as expected (no credentials passed, hence 401):

~/S/p/roc ❯❯❯ uname -a
Darwin Richards-MacBook-Pro.local 23.0.0 Darwin Kernel Version 23.0.0: Fri Sep 15 14:43:05 PDT 2023; root:xnu-10002.1.13~1/RELEASE_ARM64_T6020 arm64
~/S/p/roc ❯❯❯ roc --version
roc nightly pre-release, built from commit e65f14fa496 on Sat Dec  2 09:15:51 UTC 2023

~/S/p/roc ❯❯❯ roc dev http-network-error.roc
Request failed with status 401

But on my Windows machine running WSL2 it returns NetworkError:

~/s/b/examples ❯❯❯ uname -a
Linux DESKTOP-4Q7NKTK 5.15.133.1-microsoft-standard-WSL2 #1 SMP Thu Oct 5 21:02:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
~/s/b/examples ❯❯❯ roc --version
roc nightly pre-release, built from commit e65f14f on Sa 02 Dez 2023 09:07:00 UTC

~/s/b/examples ❯❯❯ roc dev http-network-error.roc
Network error

However, querying other API:s such as https://catfact.ninja/fact work well on WSL2 with the same example code. Also, cloning this repo and importing the platform as packages { pf: "../src/main.roc" } works with the troublesome API.

Any idea of why, or any suggestions on how to further debug?

Anton-4 commented 9 months ago

This is very strange indeed, can you double check if this was not some temporary failure? If not, can you share the OS that you are using inside WSL (Ubuntu 20.04, 22.04,...)?

wric commented 9 months ago

Issue persists today. I even rebooted the computer haha.

 Static hostname: DESKTOP-XXXX
       Icon name: computer-container
         Chassis: container
      Machine ID: 14afXXXX
         Boot ID: d9cfXXXX
  Virtualization: wsl
Operating System: Ubuntu 22.04.3 LTS
          Kernel: Linux 5.15.133.1-microsoft-standard-WSL2
    Architecture: x86-64

(XXXXs are mine. I have no idea if the id:s are sensible info).

I will try to update Ubuntu and get back.

wric commented 9 months ago
 Static hostname: DESKTOP-XXXX
       Icon name: computer-container
         Chassis: container ☐
      Machine ID: 14afXXXX
         Boot ID: be75XXXX
  Virtualization: wsl
Operating System: Ubuntu 23.04
          Kernel: Linux 5.15.133.1-microsoft-standard-WSL2
    Architecture: x86-64

Unfortunately sill NetworkError. Also tested with both roc dev and roc run, same issue.

Anton-4 commented 9 months ago

Thanks for the info @wric, I'll try to reproduce.

Anton-4 commented 9 months ago

I was able to reproduce the issue, going to dig into it now...

Anton-4 commented 9 months ago

Surprisingly, this does not reproduce on Ubuntu 22.04 native (not inside WSL).

Anton-4 commented 9 months ago

When building with the platform locally (packages { pf: "../src/main.roc" }) the issue reproduces when using export CARGO_BUILD_TARGET=x86_64-unknown-linux-musl.

Also got some more detail on the error:

[src/lib.rs:638] &res = Err(
    hyper::Error(
        Connect,
        ConnectError(
            "dns error",
            Custom {
                kind: Uncategorized,
                error: "failed to lookup address information: Name does not resolve",
            },
        ),
    ),
)

I'm done for today, but tomorrow I'm going to try to reproduce this with a pure rust program.

Anton-4 commented 9 months ago

I was able to reproduce this with pure rust: Cargo.toml:

name = "rusttemp"
version = "0.1.0"
edition = "2021"

[dependencies]
hyper = { version = "=0.14.27", default-features = false, features = ["http1", "client"] }
hyper-rustls = { version = "=0.24.2", default-features = false, features = ["http1", "tls12", "native-tokio"]}
tokio = { version = "=1.31.0", default-features = false}

src/main.rs:

fn main() {
    testrequest();
    println!("Done");
}

fn testrequest() {
    use hyper::Client;
    use hyper_rustls::HttpsConnectorBuilder;

    let https = HttpsConnectorBuilder::new()
        .with_native_roots()
        .https_or_http()
        .enable_http1()
        .build();

    let client: Client<_, hyper::Body> = Client::builder().build(https);

    let method = hyper::Method::GET;

    let url = "https://api-extern.systembolaget.se/site/V2/Search/Site";

    let mut req_builder = hyper::Request::builder().method(method).uri(url);

    let body_bytes = vec![];

    let request = req_builder.body(body_bytes.into()).unwrap();

    let rt = tokio::runtime::Builder::new_current_thread()
        .enable_io()
        .enable_time()
        .build()
        .unwrap();

    let http_fn = async {
        let res = client.request(request).await;

        dbg!(&res);
    };

     rt.block_on(http_fn);
}
Anton-4 commented 9 months ago