dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

closure invoked recursively or after being dropped

Open XavDesbordes opened this issue 1 year ago • 8 comments

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 avatar Aug 23 '24 08:08 XavDesbordes

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.

XavDesbordes avatar Aug 23 '24 12:08 XavDesbordes

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 avatar Aug 26 '24 15:08 ealmloff

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

ealmloff avatar Aug 26 '24 15:08 ealmloff

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

XavDesbordes avatar Aug 26 '24 18:08 XavDesbordes

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)

matthunz avatar Aug 29 '24 16:08 matthunz

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

XavDesbordes avatar Aug 30 '24 19:08 XavDesbordes

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"

spookyvision avatar Dec 14 '24 22:12 spookyvision

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

ealmloff avatar Dec 16 '24 20:12 ealmloff