summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2021-02-21 15:22:06 +0000
committerGitHub <noreply@github.com>2021-02-21 16:22:06 +0100
commit14ec22e88044cbac5fffe347535ce8ac1bdb7ec5 (patch)
tree32abc21e264e88cd4a68c1b4db60e242c81d9c27 /core
parent18b2dbf0d0f7755275dec272e49950541b11edc1 (diff)
fix(core/bindings): Add stacks for dynamic import resolution errors (#9562)
Diffstat (limited to 'core')
-rw-r--r--core/bindings.rs27
1 files changed, 27 insertions, 0 deletions
diff --git a/core/bindings.rs b/core/bindings.rs
index 1f6b85174..bb5589080 100644
--- a/core/bindings.rs
+++ b/core/bindings.rs
@@ -11,6 +11,7 @@ use futures::future::FutureExt;
use rusty_v8 as v8;
use std::cell::Cell;
use std::convert::TryFrom;
+use std::convert::TryInto;
use std::io::{stdout, Write};
use std::option::Option;
use url::Url;
@@ -205,6 +206,32 @@ pub extern "C" fn host_import_module_dynamically_callback(
state.dyn_import_cb(resolver_handle, &specifier_str, &referrer_name_str);
}
+ // Map errors from module resolution (not JS errors from module execution) to
+ // ones rethrown from this scope, so they include the call stack of the
+ // dynamic import site. Error objects without any stack frames are assumed to
+ // be module resolution errors, other exception values are left as they are.
+ let map_err = |scope: &mut v8::HandleScope,
+ args: v8::FunctionCallbackArguments,
+ _rv: v8::ReturnValue| {
+ let arg = args.get(0);
+ if arg.is_native_error() {
+ let message = v8::Exception::create_message(scope, arg);
+ if message.get_stack_trace(scope).unwrap().get_frame_count() == 0 {
+ let arg: v8::Local<v8::Object> = arg.clone().try_into().unwrap();
+ let message_key = v8::String::new(scope, "message").unwrap();
+ let message = arg.get(scope, message_key.into()).unwrap();
+ let exception =
+ v8::Exception::type_error(scope, message.try_into().unwrap());
+ scope.throw_exception(exception);
+ return;
+ }
+ }
+ scope.throw_exception(arg);
+ };
+ let map_err = v8::FunctionTemplate::new(scope, map_err);
+ let map_err = map_err.get_function(scope).unwrap();
+ let promise = promise.catch(scope, map_err).unwrap();
+
&*promise as *const _ as *mut _
}