diff --git a/crates/cli/tests/dynamic_linking_test.rs b/crates/cli/tests/dynamic_linking_test.rs index 12b4ffdf..cd5a0d27 100644 --- a/crates/cli/tests/dynamic_linking_test.rs +++ b/crates/cli/tests/dynamic_linking_test.rs @@ -46,6 +46,25 @@ pub fn test_dynamic_linking_with_func_without_flag() -> Result<()> { Ok(()) } +#[test] +fn test_errors_in_exported_functions_are_correctly_reported() -> Result<()> { + let js_src = "export function foo() { throw \"Error\" }"; + let wit = " + package local:main + + world foo-test { + export foo: func() + } + "; + let res = invoke_fn_on_generated_module(js_src, "foo", Some((wit, "foo-test")), None, None); + assert!(res + .err() + .unwrap() + .to_string() + .contains("error while executing")); + Ok(()) +} + #[test] pub fn check_for_new_imports() -> Result<()> { // If you need to change this test, then you've likely made a breaking change. diff --git a/crates/core/src/execution.rs b/crates/core/src/execution.rs index 9e026b39..bf73dfb0 100644 --- a/crates/core/src/execution.rs +++ b/crates/core/src/execution.rs @@ -61,10 +61,24 @@ pub fn invoke_function(runtime: &Runtime, fn_module: &str, fn_name: &str) { let mut opts = EvalOptions::default(); opts.strict = false; opts.global = false; - this.eval_with_options::, _>(js, opts) - .map_err(|e| from_js_error(this.clone(), e)) - .map(|_| ()) + let value = this.eval_with_options::, _>(js, opts)?; + + if let Some(promise) = value.as_promise() { + if cfg!(feature = "experimental_event_loop") { + // If the experimental event loop is enabled, trigger it. + promise.finish::().map(|_| ()) + } else { + // Else we simply expect the promise to resolve immediately. + match promise.result() { + None => Err(to_js_error(this, anyhow!(EVENT_LOOP_ERR))), + Some(r) => r, + } + } + } else { + Ok(()) + } }) + .map_err(|e| runtime.context().with(|cx| from_js_error(cx.clone(), e))) .and_then(|_: ()| process_event_loop(runtime)) .unwrap_or_else(handle_error) }