Skip to content

Commit 4434596

Browse files
committed
src: add error formatting support
1 parent 3b2863d commit 4434596

File tree

4 files changed

+52
-29
lines changed

4 files changed

+52
-29
lines changed

doc/api/errors.md

+5
Original file line numberDiff line numberDiff line change
@@ -2323,6 +2323,11 @@ than the parent module. Linked modules must share the same context.
23232323

23242324
The linker function returned a module for which linking has failed.
23252325

2326+
<a id="ERR_VM_MODULE_LINK_FAILURE"></a>
2327+
### `ERR_VM_MODULE_LINK_FAILURE`
2328+
2329+
The module was unable to be linked due to a failure.
2330+
23262331
<a id="ERR_VM_MODULE_NOT_MODULE"></a>
23272332
### `ERR_VM_MODULE_NOT_MODULE`
23282333

lib/internal/vm/module.js

+2
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ class SourceTextModule extends Module {
317317
throw new ERR_VM_MODULE_DIFFERENT_CONTEXT();
318318
}
319319
if (module.status === 'errored') {
320+
// TODO(devsnek): replace with ERR_VM_MODULE_LINK_FAILURE
321+
// and error cause proposal.
320322
throw new ERR_VM_MODULE_LINKING_ERRORED();
321323
}
322324
if (module.status === 'unlinked') {

src/module_wrap.cc

+14-10
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,9 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
297297
Local<Value> resolve_return_value =
298298
maybe_resolve_return_value.ToLocalChecked();
299299
if (!resolve_return_value->IsPromise()) {
300-
env->ThrowError("linking error, expected resolver to return a promise");
300+
THROW_ERR_VM_MODULE_LINK_FAILURE(
301+
env, "request for '%s' did not return promise", specifier_std);
302+
return;
301303
}
302304
Local<Promise> resolve_promise = resolve_return_value.As<Promise>();
303305
obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
@@ -497,33 +499,35 @@ MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
497499

498500
Isolate* isolate = env->isolate();
499501

502+
Utf8Value specifier_utf8(isolate, specifier);
503+
std::string specifier_std(*specifier_utf8, specifier_utf8.length());
504+
500505
ModuleWrap* dependent = GetFromModule(env, referrer);
501506
if (dependent == nullptr) {
502-
env->ThrowError("linking error, null dep");
507+
THROW_ERR_VM_MODULE_LINK_FAILURE(
508+
env, "request for '%s' is from invalid module", specifier_std);
503509
return MaybeLocal<Module>();
504510
}
505511

506-
Utf8Value specifier_utf8(isolate, specifier);
507-
std::string specifier_std(*specifier_utf8, specifier_utf8.length());
508-
509512
if (dependent->resolve_cache_.count(specifier_std) != 1) {
510-
env->ThrowError("linking error, not in local cache");
513+
THROW_ERR_VM_MODULE_LINK_FAILURE(
514+
env, "request for '%s' is not in cache", specifier_std);
511515
return MaybeLocal<Module>();
512516
}
513517

514518
Local<Promise> resolve_promise =
515519
dependent->resolve_cache_[specifier_std].Get(isolate);
516520

517521
if (resolve_promise->State() != Promise::kFulfilled) {
518-
env->ThrowError("linking error, dependency promises must be resolved on "
519-
"instantiate");
522+
THROW_ERR_VM_MODULE_LINK_FAILURE(
523+
env, "request for '%s' is not yet fulfilled", specifier_std);
520524
return MaybeLocal<Module>();
521525
}
522526

523527
Local<Object> module_object = resolve_promise->Result().As<Object>();
524528
if (module_object.IsEmpty() || !module_object->IsObject()) {
525-
env->ThrowError("linking error, expected a valid module object from "
526-
"resolver");
529+
THROW_ERR_VM_MODULE_LINK_FAILURE(
530+
env, "request for '%s' did not return an object", specifier_std);
527531
return MaybeLocal<Module>();
528532
}
529533

src/node_errors.h

+31-19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55

6+
#include "debug_utils-inl.h"
67
#include "env.h"
78
#include "v8.h"
89

@@ -75,29 +76,40 @@ void OnFatalError(const char* location, const char* message);
7576
V(ERR_TLS_INVALID_PROTOCOL_METHOD, TypeError) \
7677
V(ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED, Error) \
7778
V(ERR_VM_MODULE_CACHED_DATA_REJECTED, Error) \
79+
V(ERR_VM_MODULE_LINK_FAILURE, Error) \
7880
V(ERR_WASI_NOT_STARTED, Error) \
7981
V(ERR_WORKER_INIT_FAILED, Error) \
80-
V(ERR_PROTO_ACCESS, Error) \
82+
V(ERR_PROTO_ACCESS, Error)
8183

82-
#define V(code, type) \
83-
inline v8::Local<v8::Value> code(v8::Isolate* isolate, \
84-
const char* message) { \
85-
v8::Local<v8::String> js_code = OneByteString(isolate, #code); \
86-
v8::Local<v8::String> js_msg = OneByteString(isolate, message); \
87-
v8::Local<v8::Object> e = \
88-
v8::Exception::type(js_msg)->ToObject( \
89-
isolate->GetCurrentContext()).ToLocalChecked(); \
90-
e->Set(isolate->GetCurrentContext(), OneByteString(isolate, "code"), \
91-
js_code).Check(); \
92-
return e; \
93-
} \
94-
inline void THROW_ ## code(v8::Isolate* isolate, const char* message) { \
95-
isolate->ThrowException(code(isolate, message)); \
96-
} \
97-
inline void THROW_ ## code(Environment* env, const char* message) { \
98-
THROW_ ## code(env->isolate(), message); \
84+
#define V(code, type) \
85+
template <typename... Args> \
86+
inline v8::Local<v8::Value> code( \
87+
v8::Isolate* isolate, const char* format, Args&&... args) { \
88+
std::string message = SPrintF(format, std::forward<Args>(args)...); \
89+
v8::Local<v8::String> js_code = OneByteString(isolate, #code); \
90+
v8::Local<v8::String> js_msg = \
91+
OneByteString(isolate, message.c_str(), message.length()); \
92+
v8::Local<v8::Object> e = v8::Exception::type(js_msg) \
93+
->ToObject(isolate->GetCurrentContext()) \
94+
.ToLocalChecked(); \
95+
e->Set(isolate->GetCurrentContext(), \
96+
OneByteString(isolate, "code"), \
97+
js_code) \
98+
.Check(); \
99+
return e; \
100+
} \
101+
template <typename... Args> \
102+
inline void THROW_##code( \
103+
v8::Isolate* isolate, const char* format, Args&&... args) { \
104+
isolate->ThrowException( \
105+
code(isolate, format, std::forward<Args>(args)...)); \
106+
} \
107+
template <typename... Args> \
108+
inline void THROW_##code( \
109+
Environment* env, const char* format, Args&&... args) { \
110+
THROW_##code(env->isolate(), format, std::forward<Args>(args)...); \
99111
}
100-
ERRORS_WITH_CODE(V)
112+
ERRORS_WITH_CODE(V)
101113
#undef V
102114

103115
// Errors with predefined static messages

0 commit comments

Comments
 (0)