2525#include " env-inl.h"
2626
2727namespace node {
28+
29+ namespace per_process {
30+ struct UVError {
31+ int value;
32+ const char * name;
33+ const char * message;
34+ };
35+
36+ // We only expand the macro once here to reduce the amount of code
37+ // generated.
38+ static const struct UVError uv_errors_map[] = {
39+ #define V (name, message ) {UV_##name, #name, message},
40+ UV_ERRNO_MAP (V)
41+ #undef V
42+ };
43+ } // namespace per_process
44+
2845namespace {
2946
3047using v8::Array;
3148using v8::Context;
49+ using v8::DontDelete;
3250using v8::FunctionCallbackInfo;
3351using v8::Integer;
3452using v8::Isolate;
3553using v8::Local;
3654using v8::Map;
3755using v8::Object;
56+ using v8::PropertyAttribute;
57+ using v8::ReadOnly;
3858using v8::String;
3959using v8::Value;
4060
41-
4261void ErrName (const FunctionCallbackInfo<Value>& args) {
4362 Environment* env = Environment::GetCurrent (args);
4463 if (env->options ()->pending_deprecation && env->EmitErrNameWarning ()) {
@@ -57,6 +76,29 @@ void ErrName(const FunctionCallbackInfo<Value>& args) {
5776 args.GetReturnValue ().Set (OneByteString (env->isolate (), name));
5877}
5978
79+ void GetErrMap (const FunctionCallbackInfo<Value>& args) {
80+ Environment* env = Environment::GetCurrent (args);
81+ Isolate* isolate = env->isolate ();
82+ Local<Context> context = env->context ();
83+
84+ Local<Map> err_map = Map::New (isolate);
85+
86+ size_t errors_len = arraysize (per_process::uv_errors_map);
87+ for (size_t i = 0 ; i < errors_len; ++i) {
88+ const auto & error = per_process::uv_errors_map[i];
89+ Local<Value> arr[] = {OneByteString (isolate, error.name ),
90+ OneByteString (isolate, error.message )};
91+ if (err_map
92+ ->Set (context,
93+ Integer::New (isolate, error.value ),
94+ Array::New (isolate, arr, arraysize (arr)))
95+ .IsEmpty ()) {
96+ return ;
97+ }
98+ }
99+
100+ args.GetReturnValue ().Set (err_map);
101+ }
60102
61103void Initialize (Local<Object> target,
62104 Local<Value> unused,
@@ -70,28 +112,21 @@ void Initialize(Local<Object> target,
70112 ->GetFunction (env->context ())
71113 .ToLocalChecked ()).FromJust ();
72114
73- #define V (name, _ ) NODE_DEFINE_CONSTANT(target, UV_##name);
74- UV_ERRNO_MAP (V)
75- #undef V
76-
77- Local<Map> err_map = Map::New (isolate);
78-
79- #define V (name, msg ) do { \
80- Local<Value> arr[] = { \
81- OneByteString (isolate, #name), \
82- OneByteString (isolate, msg) \
83- }; \
84- if (err_map->Set (context, \
85- Integer::New (isolate, UV_##name), \
86- Array::New (isolate, arr, arraysize (arr))).IsEmpty ()) { \
87- return ; \
88- } \
89- } while (0 );
90- UV_ERRNO_MAP (V)
91- #undef V
115+ // TODO(joyeecheung): This should be deprecated in user land in favor of
116+ // `util.getSystemErrorName(err)`.
117+ PropertyAttribute attributes =
118+ static_cast <PropertyAttribute>(ReadOnly | DontDelete);
119+ size_t errors_len = arraysize (per_process::uv_errors_map);
120+ const std::string prefix = " UV_" ;
121+ for (size_t i = 0 ; i < errors_len; ++i) {
122+ const auto & error = per_process::uv_errors_map[i];
123+ const std::string prefixed_name = prefix + error.name ;
124+ Local<String> name = OneByteString (isolate, prefixed_name.c_str ());
125+ Local<Integer> value = Integer::New (isolate, error.value );
126+ target->DefineOwnProperty (context, name, value, attributes).FromJust ();
127+ }
92128
93- target->Set (context, FIXED_ONE_BYTE_STRING (isolate, " errmap" ),
94- err_map).FromJust ();
129+ env->SetMethod (target, " getErrorMap" , GetErrMap);
95130}
96131
97132} // anonymous namespace
0 commit comments