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

closure invoked recursively or after being dropped #2882

Closed
XavDesbordes opened this issue Aug 23, 2024 · 8 comments · Fixed by #3405
Closed

closure invoked recursively or after being dropped #2882

XavDesbordes opened this issue Aug 23, 2024 · 8 comments · Fixed by #3405
Labels
bug Something isn't working web relating to the web renderer for dioxus

Comments

@XavDesbordes
Copy link

Hello,

I have an issue with a simple app, running 0.5.6:

#[server]
pub(crate) async fn test() -> Result<Vec<u8>, ServerFnError> {
    Ok(vec![])
}
#[component]
pub fn MySection(url: String) -> Element {
    let ret = use_resource(move || async move { test().await });

    rsx! {
        match &*ret.read() {
            Some(Ok(_)) =>
                rsx! {
                    "OK"
                },
            Some(Err(e)) => rsx! { p { "Loading failed, {e}" } },
            None => rsx! { p { "Loading..." } },
        }
    }
}

the error, in console (chrome and firefox):

Error: closure invoked recursively or after being dropped
    at imports.wbg.__wbindgen_throw (my-crate.js:1351:15)
    at my_crate-6606e411e9d76bf3.wasm.wasm_bindgen::throw_str::h488655a78d764f53 (my-crate_bg.wasm:0xc1b9b)
    at my_crate-6606e411e9d76bf3.wasm.<dyn core::ops::function::FnMut<(A,)>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h9234fc5187b811e0 (http://localhost:8080/assets/dioxus/my-crate_bg.wasm)
    at __wbg_adapter_56 (my-crate.js:300:10)
    at real (my-crate.js:265:20)

The result is loaded, the page shows "OK" but this error arises in my console log as the last element.
Note: I replaced the app names above.

What is happening ?
How to avoid this ?

Thanks!

@XavDesbordes
Copy link
Author

XavDesbordes commented Aug 23, 2024

Apparently, it's in this function:

function makeMutClosure(arg0, arg1, dtor, f) {
    const state = { a: arg0, b: arg1, cnt: 1, dtor };
    const real = (...args) => {
        // First up with a closure we increment the internal reference
        // count. This ensures that the Rust closure environment won't
        // be deallocated while we're invoking it.
        state.cnt++;
        const a = state.a;
        state.a = 0;
        try {
            return f(a, state.b, ...args); <- HERE
        } finally {
            if (--state.cnt === 0) {
                wasm.__wbindgen_export_2.get(state.dtor)(a, state.b);
                CLOSURE_DTORS.unregister(state);
            } else {
                state.a = a;
            }
        }
    };
    real.original = state;
    CLOSURE_DTORS.register(real, state, state);
    return real;
}

I read that there may be a missing .forget() somewhere.

@ealmloff ealmloff added the needs reproduction An issue that is missing a reproduction label Aug 26, 2024
@ealmloff
Copy link
Member

I cannot reproduce the issue with this code:
Cargo.toml

[dependencies]
dioxus = { version = "0.5", features = ["fullstack"] } 

[features]
web = ["dioxus/web"]
server = ["dioxus/axum"]

main.rs

use dioxus::prelude::*;

fn main() {
    launch(App);
}

#[component]
fn App() -> Element {
    rsx! {
        MySection {
            url: "https://www.google.com".to_string()
        }
    }
}

#[server]
pub(crate) async fn test() -> Result<Vec<u8>, ServerFnError> {
    Ok(vec![])
}

#[component]
pub fn MySection(url: String) -> Element {
    let ret = use_resource(move || async move { test().await });

    rsx! {
        match &*ret.read() {
            Some(Ok(_)) =>
                rsx! {
                    "OK"
                },
            Some(Err(e)) => rsx! { p { "Loading failed, {e}" } },
            None => rsx! { p { "Loading..." } },
        }
    }
}

@ealmloff
Copy link
Member

We use several web-sys closures in dioxus-web. If you are interested in debugging this issue, you can try to track down which closure is causing issues by adding dioxus-logger and adding logs to each closure passed to javascript in dioxus-web

@XavDesbordes
Copy link
Author

@ealmloff : Yes I will check that in the next hours !

@matthunz
Copy link
Contributor

I can’t reproduce this either 🤔 do you have any other errors in the console above that? I think it’s somewhat of a known issue that wasm_bindgen will report that error after Rust panics (I think while you’re inside a closure)

@XavDesbordes
Copy link
Author

Well, I changed the code for some inputs and now it's impossible to reproduce.
I am pretty sure it's linked to an async function that went wrong. And we corrected many in the meantime.

I will close for now, but if it appears again, I will reopen.

Thanks guys

@spookyvision
Copy link
Contributor

spookyvision commented Dec 14, 2024

I ran into this, seems to be (in my case) caused by two event handlers firing: removing the onfocus handler gets rid of the crash.
clicking the green div triggers the panic (dioxus web, Firefox 133.0.3 on Mac).

use dioxus::{prelude::*, web::WebEventExt};
use dioxus_logger::tracing::{debug, Level};
use wasm_bindgen::JsCast;
use web_sys::HtmlInputElement;

fn main() {
    dioxus_logger::init(Level::DEBUG).expect("failed to init logger");
    dioxus::launch(App);
}

#[component]
fn App() -> Element {
    let mut input_el: Signal<Option<HtmlInputElement>> = use_signal(|| None);

    rsx! {
        div {
            style: "width: 100vw; height:100vh; background-color: lime;",
            onclick: move |_ev| {
                if let Some(input_el) = input_el.as_ref() {
                    input_el.focus().ok();
                }
            },
            input {
                onmounted: move |ev| {
                    let el = ev.as_web_event();
                    if let Ok(el) = el.dyn_into::<HtmlInputElement>() {
                        input_el.set(Some(el))
                    }
                },
                onfocus: move |_ev| {
                    debug!("search::focus");
                },
            }
        }
    }
}
[package]
name = "crash"
version = "0.1.0"
authors = ["spookyvision"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
dioxus = { version = "0.6.0", features = [] }
dioxus-logger = "0.6.0"
wasm-bindgen = "0.2.99"
web-sys = { version = "0.3.76", features = ["Element", "HtmlInputElement"] }

[features]
default = ["web"]
web = ["dioxus/web"]
desktop = ["dioxus/desktop"]
mobile = ["dioxus/mobile"]

[profile]

[profile.wasm-dev]
inherits = "dev"
opt-level = 1

[profile.server-dev]
inherits = "dev"

[profile.android-dev]
inherits = "dev"

@ealmloff ealmloff reopened this Dec 16, 2024
@ealmloff ealmloff added bug Something isn't working web relating to the web renderer for dioxus and removed needs reproduction An issue that is missing a reproduction labels Dec 16, 2024
@ealmloff
Copy link
Member

I ran into this, seems to be (in my case) caused by two event handlers firing: removing the onfocus handler gets rid of the crash. clicking the green div triggers the panic (dioxus web, Firefox 133.0.3 on Mac).

Thanks for creating a reproduction. I reproduce the panic on MacOs in chrome as well

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

Successfully merging a pull request may close this issue.

4 participants