25
25
#include " env-inl.h"
26
26
27
27
namespace 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
+
28
45
namespace {
29
46
30
47
using v8::Array;
31
48
using v8::Context;
49
+ using v8::DontDelete;
32
50
using v8::FunctionCallbackInfo;
33
51
using v8::Integer;
34
52
using v8::Isolate;
35
53
using v8::Local;
36
54
using v8::Map;
37
55
using v8::Object;
56
+ using v8::PropertyAttribute;
57
+ using v8::ReadOnly;
38
58
using v8::String;
39
59
using v8::Value;
40
60
41
-
42
61
void ErrName (const FunctionCallbackInfo<Value>& args) {
43
62
Environment* env = Environment::GetCurrent (args);
44
63
if (env->options ()->pending_deprecation && env->EmitErrNameWarning ()) {
@@ -57,6 +76,29 @@ void ErrName(const FunctionCallbackInfo<Value>& args) {
57
76
args.GetReturnValue ().Set (OneByteString (env->isolate (), name));
58
77
}
59
78
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
+ }
60
102
61
103
void Initialize (Local<Object> target,
62
104
Local<Value> unused,
@@ -70,28 +112,21 @@ void Initialize(Local<Object> target,
70
112
->GetFunction (env->context ())
71
113
.ToLocalChecked ()).FromJust ();
72
114
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
+ }
92
128
93
- target->Set (context, FIXED_ONE_BYTE_STRING (isolate, " errmap" ),
94
- err_map).FromJust ();
129
+ env->SetMethod (target, " getErrorMap" , GetErrMap);
95
130
}
96
131
97
132
} // anonymous namespace
0 commit comments