stdweb icon indicating copy to clipboard operation
stdweb copied to clipboard

"Uncaught exception" when calling rust function from event callback

Open shelvacu opened this issue 5 years ago • 4 comments

#[macro_use]
extern crate stdweb;

fn bla(){
    println!("blarg");
}

fn main() {
    js!{
        document.addEventListener("click", @{bla} );
    }
}

Click anywhere on page with console open, see bug.

shelvacu avatar Oct 16 '18 02:10 shelvacu

This is expected. The way a function is called from JS must match the prototype of the function on Rust's side. In this case the function you've set as the event handler will get called with a single argument (which will be the event object), and you've passed it a function which takes no arguments. This will fail at runtime.

The error you're getting could probably be more descriptive; I have plans to improve them.

Anyhow, you should probably use IEventTarget::add_event_listener if you want to set an event handler.

koute avatar Oct 18 '18 19:10 koute

Sorry about that, was trying to create the simplest possible repro case.

If you change it to use an anonymous function like so

document.addEventListener("click", function(){@{bla}()})

then, at least on my copy of firefox, it does not print "blarg" in the console as it should. It does say warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling

shelvacu avatar Oct 18 '18 20:10 shelvacu

Updated example, doesn't use addEventListener:

#[macro_use]
extern crate stdweb;

fn say( msg:String ){
    println!("I say: {}", msg);
}

fn main() {
    js!{
        let say = @{say};
        say("a");
        (function(){say("b")})();
        setTimeout(function(){say("c")},100);
    }
}

shelvacu avatar Oct 18 '18 20:10 shelvacu

Hmmm... this happens because you haven't called stdweb::event_loop, so Emscripten's runtime gets deinitialized. (Or maybe it's only Rust's runtime? I'll need to check.)

I could have sworn this used to work....

Thanks for the report! Reopening!

koute avatar Oct 18 '18 21:10 koute