diff --git a/doc/api/errors.md b/doc/api/errors.md
index ca3de99de9e636f..f0d78854703a416 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -2323,6 +2323,11 @@ than the parent module. Linked modules must share the same context.
The linker function returned a module for which linking has failed.
+
+### `ERR_VM_MODULE_LINK_FAILURE`
+
+The module was unable to be linked due to a failure.
+
### `ERR_VM_MODULE_NOT_MODULE`
diff --git a/lib/internal/vm/module.js b/lib/internal/vm/module.js
index 56164b0d8b98d4b..3052d21e1a42fe2 100644
--- a/lib/internal/vm/module.js
+++ b/lib/internal/vm/module.js
@@ -317,6 +317,8 @@ class SourceTextModule extends Module {
throw new ERR_VM_MODULE_DIFFERENT_CONTEXT();
}
if (module.status === 'errored') {
+ // TODO(devsnek): replace with ERR_VM_MODULE_LINK_FAILURE
+ // and error cause proposal.
throw new ERR_VM_MODULE_LINKING_ERRORED();
}
if (module.status === 'unlinked') {
diff --git a/src/module_wrap.cc b/src/module_wrap.cc
index f4a7ad6b0c3eeec..1fb2ea433078583 100644
--- a/src/module_wrap.cc
+++ b/src/module_wrap.cc
@@ -297,7 +297,9 @@ void ModuleWrap::Link(const FunctionCallbackInfo& args) {
Local resolve_return_value =
maybe_resolve_return_value.ToLocalChecked();
if (!resolve_return_value->IsPromise()) {
- env->ThrowError("linking error, expected resolver to return a promise");
+ THROW_ERR_VM_MODULE_LINK_FAILURE(
+ env, "request for '%s' did not return promise", specifier_std);
+ return;
}
Local resolve_promise = resolve_return_value.As();
obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
@@ -497,17 +499,19 @@ MaybeLocal ModuleWrap::ResolveModuleCallback(
Isolate* isolate = env->isolate();
+ Utf8Value specifier_utf8(isolate, specifier);
+ std::string specifier_std(*specifier_utf8, specifier_utf8.length());
+
ModuleWrap* dependent = GetFromModule(env, referrer);
if (dependent == nullptr) {
- env->ThrowError("linking error, null dep");
+ THROW_ERR_VM_MODULE_LINK_FAILURE(
+ env, "request for '%s' is from invalid module", specifier_std);
return MaybeLocal();
}
- Utf8Value specifier_utf8(isolate, specifier);
- std::string specifier_std(*specifier_utf8, specifier_utf8.length());
-
if (dependent->resolve_cache_.count(specifier_std) != 1) {
- env->ThrowError("linking error, not in local cache");
+ THROW_ERR_VM_MODULE_LINK_FAILURE(
+ env, "request for '%s' is not in cache", specifier_std);
return MaybeLocal();
}
@@ -515,15 +519,15 @@ MaybeLocal ModuleWrap::ResolveModuleCallback(
dependent->resolve_cache_[specifier_std].Get(isolate);
if (resolve_promise->State() != Promise::kFulfilled) {
- env->ThrowError("linking error, dependency promises must be resolved on "
- "instantiate");
+ THROW_ERR_VM_MODULE_LINK_FAILURE(
+ env, "request for '%s' is not yet fulfilled", specifier_std);
return MaybeLocal();
}
Local