Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http::Request::send panics in Node with wasm-pack #484

Closed
littlebenlittle opened this issue Jul 17, 2024 · 6 comments
Closed

http::Request::send panics in Node with wasm-pack #484

littlebenlittle opened this issue Jul 17, 2024 · 6 comments
Labels
bug Something isn't working

Comments

@littlebenlittle
Copy link
Contributor

littlebenlittle commented Jul 17, 2024

Describe the Bug

Calls to http::Request::send reach the panic condition here in NodeJS environment.

Steps to Reproduce

Full crate:
gloo_node.tar.gz

Run:

wasm-pack build --target nodejs
node index.js

Node Version: v21.6.1

Code:

extern crate console_error_panic_hook;
extern crate wasm_bindgen;

use std::panic;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn main() {
    panic::set_hook(Box::new(console_error_panic_hook::hook));
    wasm_bindgen_futures::spawn_local(async move {
        gloo_net::http::Request::get("localhost:8080")
            .send() // panics
            .await
            .unwrap();
    });
}

Additional Info

Seems to be the result of undefined WorkerGlobalScope. Node v21+ defines fetch on the global context (ref) so something like this might work?

pub async fn send(self) -> Result<Response, Error> {
        let request = self.0;
        let global = js_sys::global();
        let maybe_window =
            Reflect::get(&global, &JsValue::from_str("Window")).map_err(js_to_error)?;
        let promise = if !maybe_window.is_undefined() {
            let window = global.dyn_into::<web_sys::Window>().unwrap();
            window.fetch_with_request(&request)
        } else {
            let maybe_worker = Reflect::get(&global, &JsValue::from_str("WorkerGlobalScope"))
                .map_err(js_to_error)?;
            if !maybe_worker.is_undefined() {
                let worker = global.dyn_into::<web_sys::WorkerGlobalScope>().unwrap();
                worker.fetch_with_request(&request)
            } else {
                // panic!("Unsupported JavaScript global context");
                // instead:
                let maybe_fetch = js_sys::Reflect::get(&global, &JsValue::from_str("fetch")).unwrap();
                if maybe_fetch.is_undefined() {
                    panic!("no global fetch()")
                }
                let fetch = maybe_fetch.dyn_into::<js_sys::Function>().unwrap();
                fetch.call1(&global, &unsafe { JsValue::from_abi(request.return_abi()) });
        }
        // ...
}
@littlebenlittle
Copy link
Contributor Author

This is not caught by the current test suite as run here.

It is caught when run with wasm-pack test --node crates/net --all-features and commenting out this line to disable non-browser environment.

@littlebenlittle littlebenlittle changed the title http::Request::send panics in Node http::Request::send panics in Node with wasm-pack Jul 18, 2024
@kunjee17
Copy link

I am getting similar kind of error for console package as well. Alert works without any issue but as soon as I add and use console or net package. it panics and doesn't work with my react project.

LinkError: WebAssembly.instantiate(): Import #4 "wbg" "__wbg_log_7c3433e130418e14": function import requires a callable

It shows this kind of cryptic message. Any help would be really appreciated.

@littlebenlittle
Copy link
Contributor Author

@kunjee17 Without more context I can only guess, but that looks like your wasm module declares a function import and the JS environment is giving it something that is not a function. I recommend opening a separate issue and providing a full example.

@kunjee17
Copy link

kunjee17 commented Jul 19, 2024

hey, @littlebenlittle thanks for replying. Here is demo repo. I am basically trying to combine moonrepo that has server written in rust. Shared logic written in rust and client that will expose part of logic to UI written in react. I know everything can be written in rust. But basically I am trying to create a logical library in wasm, that can be consume in any UI library.

Once everything installed this should make it work moon rusty:build-client && pnpm i && moon admin:dev . But if you make any function async directly or indirectly it will not work.

@littlebenlittle
Copy link
Contributor Author

Resolved by #474

@kunjee17
Copy link

@littlebenlittle Don't kill me for this. But my issue solved by deleting node_modules and reinstalling. Don't know I should be happy about it or sad. In any case thanks for help man.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants