diff --git a/doc/api/errors.md b/doc/api/errors.md
index 8135b1cc5b02ec..ece60bdbc34e2d 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -2138,6 +2138,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 72f53727d86138..a8ea29a4138531 100644
--- a/lib/internal/vm/module.js
+++ b/lib/internal/vm/module.js
@@ -324,6 +324,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 e16a226ebfb8ee..90484774eb29ab 100644
--- a/src/module_wrap.cc
+++ b/src/module_wrap.cc
@@ -291,7 +291,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);
@@ -485,17 +487,19 @@ MaybeLocal ModuleWrap::ResolveCallback(Local context,
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();
}
@@ -503,15 +507,15 @@ MaybeLocal ModuleWrap::ResolveCallback(Local context,
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