Skip to content

Unexpected Err(Finished) when receiving from an eval #3084

@StevenLove

Description

@StevenLove

Problem
I'm experiencing occasional failures when using the eval hook to run Javascript that in turn calls dioxus.send() to send a message back to Rust where I've called eval.recv().await. The problem is that eval.recv().await will sometimes return an Err(Finished).

Steps To Reproduce
I've published a public repo where you can see my approach, in a project just barely modified from the template project created by dx new.

At its core, my approach can be seen below where a button's onclick handler creates a loop that will repeatedly calculate the current timestamp and send it (using eval) to Javascript where Javascript will send it back to Rust which is using eval.recv().await. I have tried adding timeouts to delay the javascript call to dioxus.send() and tokio sleeps to delay calling eval.recv().await and have not gotten reliable success with either approach.

#[component]
fn Home() -> Element {
    let mut count = use_signal(|| 0);
    let mut local_timestamps = use_signal::<Vec<u128>>(|| vec![]);
    let mut remote_timestamps = use_signal::<Vec<u128>>(|| vec![]);

    rsx! {
        Link { to: Route::Blog { id: count() }, "Go to blog" }
        div {
            h1 { "High-Five counter: {count}" }
            button { onclick: move |_| count += 1, "Up high!" }
            button { onclick: move |_| count -= 1, "Down low!" }
            button {
                onclick: move |_| async move {
                    loop {
                        let t: u128 = std::time::SystemTime::now()
                            .duration_since(std::time::UNIX_EPOCH)
                            .unwrap()
                            .as_millis();
                        local_timestamps.push(t);
                        let mut eval = eval(
                            &format!(
                                r#"
                    let t = {t};
                    console.log("local timestamp",t);
                    dioxus.send(t);
                    "#,
                            ),
                        );
                        let received = eval.recv().await;
                        let Ok(received) = received else {
                            println!("Failure to recv! {:?}", received);
                            return;
                        };
                        let parsed = serde_json::from_value::<u128>(received).unwrap();
                        remote_timestamps.push(parsed);
                    }
                },
                "Send timestamps in a loop"
            }
        }

        div { {format!("local_timestamps: {:?}",local_timestamps)  } }
        div { {format!("remote_timestamps: {:?}", remote_timestamps)  } }
    }
}

Expected behavior
No Errors when sending simple messages back and forth with eval, dioxus.send(), and eval.recv().await

Environment:

  • Dioxus version: v0.5.6
  • Rust version: 1.81.0
  • OS info: MacOS 15.0.1
  • App platform: Desktop

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions