http-rs / surf

Fast and friendly HTTP client framework for async Rust
https://docs.rs/surf
Apache License 2.0
1.45k stars 119 forks source link

TypeError: 'clearTimeout' called on an object that does not implement interface Window #338

Open davnav opened 2 years ago

davnav commented 2 years ago

When try to run request for wasm through surf ( code snippet below) and I am getting "clearTimeout' called on an object that does not implement interface Window" I suspect following could be the issue -

  1. Is it because I am using unwrap() on the surf request ?
  2. When await.unwrap() change to await? , following errors comes in wasm-pack build "surf::error does not implement for wasm_bindgen::Jsvalue"
#[wasm_bindgen]
pub async fn run() -> Result<JsValue,JsValue>{

    let url = format!("https://api.github.com/repos/{}/branches/master","rustwasm/wasm-bindgen");
    web_sys::console::log_1(&url.clone().into()) ;
    web_sys::console::log_1(&"build surf request call".into()) ;
    let mut res  = surf::
                get(url)
                .header("accept","application/vnd.github.v3+json")
                .send()
                .await.unwrap();

    web_sys::console::log_1(&"finished surf request call".into()) ;
    let text = res.body_string().await.unwrap();
    // web_sys::console::log_1(&res.toclone().into()) ;
    let branch_json: Branch = serde_json::from_str(&text).unwrap();
    Ok(JsValue::from_serde(&branch_json).unwrap())
}

Error screenshot from browser

Source map error: Error: NetworkError when attempting to fetch resource.
Resource URL: webpack:///./node_modules/sockjs-client/dist/sockjs.js?
Source Map URL: sockjs.js.map
https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master wasmexp_bg.js:373:13
build surf request call wasmexp_bg.js:373:13
Uncaught (in promise) TypeError: 'clearTimeout' called on an object that does not implement interface Window.
    __wbg_clearTimeout_d8b36ad8fa330187 http://localhost:8080/bootstrap.js:83
    __wbg_adapter_29 webpack:///../pkg/wasmexp_bg.js?:272
    real webpack:///../pkg/wasmexp_bg.js?:253
    promise callback*__wbg_then_a6860c82b90816ca webpack:///../pkg/wasmexp_bg.js?:510
    __wbg_then_a6860c82b90816ca http://localhost:8080/bootstrap.js:173
    __wbg_adapter_29 webpack:///../pkg/wasmexp_bg.js?:272
    real webpack:///../pkg/wasmexp_bg.js?:253
bootstrap.js:83:72

tobiemh commented 1 year ago

@davnav, @Fishrock123 I've recently come across this error too, and although I'm not certain it is exactly the same error, I'm pretty sure it is. The error message is different depending on the browser.

When using Surf inside WASM, which is then bundled by Webpack, the wasm-bindgen-futures crate (which is used by async_std in WASM) is trying to call clearTimeout on the future, but the global object in Webpack is not window, and therefore the function fails. I'm not sure if this is an error in the wasm-bindgen-futures crate, or if it can be handled differently within surf / http-client.

There was a similar issue in the rustwasm/gloo project which solved the problem by ensuring that clearTimeout was called on the window object specifically, and not on the global context (which isn't always Window, due to Webpack).

The line in question which causes this error (I think) is:

async_std::future::timeout(timeout, conn).await?? 

One way of getting around this error temporarily is to disable timeouts...

use surf::Client;
use surf::Config;

let client: Client = Config::new().set_timeout(None).try_into().unwrap();
let mut req = cli.get("https://google.com");
let mut res = req.send().await?;
// This now doesn't cause an error

I've looked into trying to ensure that the module context in Webpack is window, but I haven't worked out a way of doing this yet...