closure invoked recursively or after being dropped
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!
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.
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..." } },
}
}
}
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 : Yes I will check that in the next hours !
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)
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
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"
I ran into this, seems to be (in my case) caused by two event handlers firing: removing the
onfocushandler 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