diff --git a/src/module_wrap.cc b/src/module_wrap.cc index b829e4805f..729b71e905 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -144,12 +144,12 @@ ModuleWrap::ModuleWrap(Realm* realm, Local context_object, Local synthetic_evaluation_step) : BaseObject(realm, object), + url_(Utf8Value(realm->isolate(), url).ToString()), module_(realm->isolate(), module), module_hash_(module->GetIdentityHash()) { realm->env()->hash_to_module_map.emplace(module_hash_, this); object->SetInternalField(kModuleSlot, module); - object->SetInternalField(kURLSlot, url); object->SetInternalField(kModuleSourceObjectSlot, v8::Undefined(realm->isolate())); object->SetInternalField(kSyntheticEvaluationStepsSlot, @@ -968,8 +968,7 @@ void ModuleWrap::GetModuleSourceObject( obj->object()->GetInternalField(kModuleSourceObjectSlot).As(); if (module_source_object->IsUndefined()) { - Local url = obj->object()->GetInternalField(kURLSlot).As(); - THROW_ERR_SOURCE_PHASE_NOT_DEFINED(isolate, url); + THROW_ERR_SOURCE_PHASE_NOT_DEFINED(isolate, obj->url_); return; } @@ -1043,10 +1042,8 @@ MaybeLocal ModuleWrap::ResolveSourceCallback( ->GetInternalField(ModuleWrap::kModuleSourceObjectSlot) .As(); if (module_source_object->IsUndefined()) { - Local url = resolved_module->object() - ->GetInternalField(ModuleWrap::kURLSlot) - .As(); - THROW_ERR_SOURCE_PHASE_NOT_DEFINED(Isolate::GetCurrent(), url); + THROW_ERR_SOURCE_PHASE_NOT_DEFINED(Isolate::GetCurrent(), + resolved_module->url_); return {}; } CHECK(module_source_object->IsObject()); @@ -1078,17 +1075,21 @@ Maybe ModuleWrap::ResolveModule( return Nothing(); } if (!dependent->IsLinked()) { - THROW_ERR_VM_MODULE_LINK_FAILURE( - env, - "request for '%s' is from a module not been linked", - cache_key.specifier); + THROW_ERR_VM_MODULE_LINK_FAILURE(env, + "request for '%s' can not be resolved on " + "module '%s' that is not linked", + cache_key.specifier, + dependent->url_); return Nothing(); } auto it = dependent->resolve_cache_.find(cache_key); if (it == dependent->resolve_cache_.end()) { THROW_ERR_VM_MODULE_LINK_FAILURE( - env, "request for '%s' is not in cache", cache_key.specifier); + env, + "request for '%s' is not cached on module '%s'", + cache_key.specifier, + dependent->url_); return Nothing(); } diff --git a/src/module_wrap.h b/src/module_wrap.h index 03cf8d0e91..d81facabf8 100644 --- a/src/module_wrap.h +++ b/src/module_wrap.h @@ -99,7 +99,6 @@ class ModuleWrap : public BaseObject { public: enum InternalFields { kModuleSlot = BaseObject::kInternalFieldCount, - kURLSlot, kModuleSourceObjectSlot, kSyntheticEvaluationStepsSlot, kContextObjectSlot, // Object whose creation context is the target Context @@ -215,6 +214,7 @@ class ModuleWrap : public BaseObject { v8::Local import_attributes, v8::Local referrer); + std::string url_; v8::Global module_; ResolveCache resolve_cache_; contextify::ContextifyContext* contextify_context_ = nullptr; diff --git a/src/node_errors.h b/src/node_errors.h index a40f3747ab..e64ee5b1e7 100644 --- a/src/node_errors.h +++ b/src/node_errors.h @@ -295,12 +295,11 @@ inline v8::Local ERR_BUFFER_TOO_LARGE(v8::Isolate* isolate) { } inline void THROW_ERR_SOURCE_PHASE_NOT_DEFINED(v8::Isolate* isolate, - v8::Local url) { - std::string message = std::string(*v8::String::Utf8Value(isolate, url)); + const std::string& url) { return THROW_ERR_SOURCE_PHASE_NOT_DEFINED( isolate, - "Source phase import object is not defined for module %s", - message.c_str()); + "Source phase import object is not defined for module '%s'", + url); } inline v8::Local ERR_STRING_TOO_LONG(v8::Isolate* isolate) { diff --git a/test/parallel/test-vm-module-linkmodulerequests.js b/test/parallel/test-vm-module-linkmodulerequests.js index 6d9a4324e5..dfe9fa6c14 100644 --- a/test/parallel/test-vm-module-linkmodulerequests.js +++ b/test/parallel/test-vm-module-linkmodulerequests.js @@ -65,3 +65,14 @@ test('mismatch linkage', () => { code: 'ERR_MODULE_LINK_MISMATCH', }); }); + +test('instantiate error should hint about module identifier', () => { + const foo = new SourceTextModule('import bar from "bar"', { identifier: 'file://foo' }); + const bar = new SourceTextModule('import "unknown"', { identifier: 'file://bar' }); + + foo.linkRequests([bar]); + assert.throws(() => foo.instantiate(), { + message: `request for 'unknown' can not be resolved on module 'file://bar' that is not linked`, + code: 'ERR_VM_MODULE_LINK_FAILURE', + }); +});