Await for HTTP request from a library

I've a async method in my library that uses either file system or HTTP request to load external resources. However the HTTP request (reqwest) is failling because I'm awaiting it without Tokio's runtime:

match self._assets_load_via {
    MessageLocatorLoadVia::FileSystem => {
        ...
    },
    MessageLocatorLoadVia::Http => {
        ...
        for ... {
            ...
            let content = reqwest::get(reqwest::Url::parse(res_path.clone().as_ref()).unwrap())
                .await;
            ...
        }
        ...
    },
}

When I run code relying on this I'm getting:

thread 'msg_locator' panicked at 'there is no reactor running,
must be called from the context of a Tokio 1.x runtime', 
C:\Users\hando\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-1.18.2\src\runtime\context.rs:21:19

Related dependencies:

reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }

What other dependencies do you have? Do you use any kind of block_on call anywhere?

How are you testing this library? The entry point must have either a #[tokio::main] annotation, #[tokio::test] annotation, or explicitly invoke the async functions within Runtime::block_on().

1 Like

I don't use multi-threading or threads API within my library. These are the dependencies:

[dependencies]
language-tag = "0.9.0"
serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0.123"
serde_json = "1.0.62"
serde_repr = "0.1.6"
isocountry = "0.3.2"
maplit = "1.0.2"
regex = "1.4.3"
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
# unic-langid = "0.9.0"
lazy_static = "1.4.0"
lazy-regex = "0.1.4"
isolang = "1.0.0"
icu_locid = "0.1"

[dev-dependencies]
futures-await-test = "0.3.0"

My test function has a #[async_test] attribute: see the source.

#[async_test]
async fn msg_locator() {
    let mut msg_locator = MessageLocator::new(
        MessageLocatorOptions::new()
            .supported_locales(vec!["en-US"])
            .default_locale("en-US")
            .assets(MessageLocatorAssetOptions::new()
                .src("http://localhost:3000/res/lang")
                .base_file_names(vec!["_"])
                .clean_unused(true)
                .load_via(MessageLocatorLoadVia::Http))
    ); // msg_locator
    msg_locator.load(None).await;
    /*
    assert!(msg_locator.supports_locale(&parse_locale("en-US").unwrap()));
    println!("{}", msg_locator.get("_.message_id"));
    */
}

Here is the source for the loader: message_locator.rs#L163

The futures-await-test crate does not use Tokio as its runtime. Remove that dependency and use #[tokio::test] instead.

3 Likes