Skip to content

Commit 79a1cce

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

File tree

2 files changed

+56
-29
lines changed

2 files changed

+56
-29
lines changed

src/module_wrap.cc

+18-10
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,11 @@ 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,
302+
"request for '%s' did not return promise",
303+
specifier_std.c_str());
304+
return;
301305
}
302306
Local<Promise> resolve_promise = resolve_return_value.As<Promise>();
303307
obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
@@ -497,33 +501,37 @@ MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
497501

498502
Isolate* isolate = env->isolate();
499503

504+
Utf8Value specifier_utf8(isolate, specifier);
505+
std::string specifier_std(*specifier_utf8, specifier_utf8.length());
506+
500507
ModuleWrap* dependent = GetFromModule(env, referrer);
501508
if (dependent == nullptr) {
502-
env->ThrowError("linking error, null dep");
509+
THROW_ERR_VM_MODULE_LINK_FAILURE(
510+
env, "request for '%s' is from invalid module", specifier_std.c_str());
503511
return MaybeLocal<Module>();
504512
}
505513

506-
Utf8Value specifier_utf8(isolate, specifier);
507-
std::string specifier_std(*specifier_utf8, specifier_utf8.length());
508-
509514
if (dependent->resolve_cache_.count(specifier_std) != 1) {
510-
env->ThrowError("linking error, not in local cache");
515+
THROW_ERR_VM_MODULE_LINK_FAILURE(
516+
env, "request for '%s' is not in cache", specifier_std.c_str());
511517
return MaybeLocal<Module>();
512518
}
513519

514520
Local<Promise> resolve_promise =
515521
dependent->resolve_cache_[specifier_std].Get(isolate);
516522

517523
if (resolve_promise->State() != Promise::kFulfilled) {
518-
env->ThrowError("linking error, dependency promises must be resolved on "
519-
"instantiate");
524+
THROW_ERR_VM_MODULE_LINK_FAILURE(
525+
env, "request for '%s' is not yet fulfilled", specifier_std.c_str());
520526
return MaybeLocal<Module>();
521527
}
522528

523529
Local<Object> module_object = resolve_promise->Result().As<Object>();
524530
if (module_object.IsEmpty() || !module_object->IsObject()) {
525-
env->ThrowError("linking error, expected a valid module object from "
526-
"resolver");
531+
THROW_ERR_VM_MODULE_LINK_FAILURE(
532+
env,
533+
"request for '%s' did not return an object",
534+
specifier_std.c_str());
527535
return MaybeLocal<Module>();
528536
}
529537

src/node_errors.h

+38-19
Original file line numberDiff line numberDiff line change
@@ -75,29 +75,48 @@ void OnFatalError(const char* location, const char* message);
7575
V(ERR_TLS_INVALID_PROTOCOL_METHOD, TypeError) \
7676
V(ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED, Error) \
7777
V(ERR_VM_MODULE_CACHED_DATA_REJECTED, Error) \
78+
V(ERR_VM_MODULE_LINK_FAILURE, Error) \
7879
V(ERR_WASI_NOT_STARTED, Error) \
7980
V(ERR_WORKER_INIT_FAILED, Error) \
80-
V(ERR_PROTO_ACCESS, Error) \
81+
V(ERR_PROTO_ACCESS, Error)
8182

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); \
83+
#define V(code, type) \
84+
inline v8::Local<v8::Value> code( \
85+
v8::Isolate* isolate, const char* message, va_list args) { \
86+
v8::Local<v8::String> js_code = OneByteString(isolate, #code); \
87+
char buffer[256]; \
88+
vsprintf(buffer, message, args); \
89+
v8::Local<v8::String> js_msg = OneByteString(isolate, buffer); \
90+
v8::Local<v8::Object> e = v8::Exception::type(js_msg) \
91+
->ToObject(isolate->GetCurrentContext()) \
92+
.ToLocalChecked(); \
93+
e->Set(isolate->GetCurrentContext(), \
94+
OneByteString(isolate, "code"), \
95+
js_code) \
96+
.Check(); \
97+
return e; \
98+
} \
99+
inline v8::Local<v8::Value> code( \
100+
v8::Isolate* isolate, const char* message, ...) { \
101+
va_list args; \
102+
va_start(args, message); \
103+
v8::Local<v8::Value> e = code(isolate, message, args); \
104+
va_end(args); \
105+
return e; \
106+
} \
107+
inline void THROW_##code(v8::Isolate* isolate, const char* message, ...) { \
108+
va_list args; \
109+
va_start(args, message); \
110+
isolate->ThrowException(code(isolate, message, args)); \
111+
va_end(args); \
112+
} \
113+
inline void THROW_##code(Environment* env, const char* message, ...) { \
114+
va_list args; \
115+
va_start(args, message); \
116+
env->isolate()->ThrowException(code(env->isolate(), message, args)); \
117+
va_end(args); \
99118
}
100-
ERRORS_WITH_CODE(V)
119+
ERRORS_WITH_CODE(V)
101120
#undef V
102121

103122
// Errors with predefined static messages

0 commit comments

Comments
 (0)