diff --git a/src/module_wrap.cc b/src/module_wrap.cc index f4a7ad6b0c3eeec..48058309d6703ea 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -297,7 +297,11 @@ 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.c_str()); + return; } Local resolve_promise = resolve_return_value.As(); obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise); @@ -497,17 +501,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.c_str()); 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.c_str()); return MaybeLocal(); } @@ -515,15 +521,17 @@ 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.c_str()); return MaybeLocal(); } Local module_object = resolve_promise->Result().As(); if (module_object.IsEmpty() || !module_object->IsObject()) { - env->ThrowError("linking error, expected a valid module object from " - "resolver"); + THROW_ERR_VM_MODULE_LINK_FAILURE( + env, + "request for '%s' did not return an object", + specifier_std.c_str()); return MaybeLocal(); } diff --git a/src/node_errors.h b/src/node_errors.h index 984603c42e26183..17d0ab1e6711404 100644 --- a/src/node_errors.h +++ b/src/node_errors.h @@ -75,29 +75,48 @@ void OnFatalError(const char* location, const char* message); V(ERR_TLS_INVALID_PROTOCOL_METHOD, TypeError) \ V(ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED, Error) \ V(ERR_VM_MODULE_CACHED_DATA_REJECTED, Error) \ + V(ERR_VM_MODULE_LINK_FAILURE, Error) \ V(ERR_WASI_NOT_STARTED, Error) \ V(ERR_WORKER_INIT_FAILED, Error) \ - V(ERR_PROTO_ACCESS, Error) \ + V(ERR_PROTO_ACCESS, Error) -#define V(code, type) \ - inline v8::Local code(v8::Isolate* isolate, \ - const char* message) { \ - v8::Local js_code = OneByteString(isolate, #code); \ - v8::Local js_msg = OneByteString(isolate, message); \ - v8::Local e = \ - v8::Exception::type(js_msg)->ToObject( \ - isolate->GetCurrentContext()).ToLocalChecked(); \ - e->Set(isolate->GetCurrentContext(), OneByteString(isolate, "code"), \ - js_code).Check(); \ - return e; \ - } \ - inline void THROW_ ## code(v8::Isolate* isolate, const char* message) { \ - isolate->ThrowException(code(isolate, message)); \ - } \ - inline void THROW_ ## code(Environment* env, const char* message) { \ - THROW_ ## code(env->isolate(), message); \ +#define V(code, type) \ + inline v8::Local code( \ + v8::Isolate* isolate, const char* message, va_list args) { \ + v8::Local js_code = OneByteString(isolate, #code); \ + char buffer[256]; \ + vsprintf(buffer, message, args); \ + v8::Local js_msg = OneByteString(isolate, buffer); \ + v8::Local e = v8::Exception::type(js_msg) \ + ->ToObject(isolate->GetCurrentContext()) \ + .ToLocalChecked(); \ + e->Set(isolate->GetCurrentContext(), \ + OneByteString(isolate, "code"), \ + js_code) \ + .Check(); \ + return e; \ + } \ + inline v8::Local code( \ + v8::Isolate* isolate, const char* message, ...) { \ + va_list args; \ + va_start(args, message); \ + v8::Local e = code(isolate, message, args); \ + va_end(args); \ + return e; \ + } \ + inline void THROW_##code(v8::Isolate* isolate, const char* message, ...) { \ + va_list args; \ + va_start(args, message); \ + isolate->ThrowException(code(isolate, message, args)); \ + va_end(args); \ + } \ + inline void THROW_##code(Environment* env, const char* message, ...) { \ + va_list args; \ + va_start(args, message); \ + env->isolate()->ThrowException(code(env->isolate(), message, args)); \ + va_end(args); \ } - ERRORS_WITH_CODE(V) +ERRORS_WITH_CODE(V) #undef V // Errors with predefined static messages