Skip to content

Commit 010ad8c

Browse files
jasnellMylesBorins
authored andcommitted
src: move *Exceptions out to separate cc/h
PR-URL: #20789 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
1 parent 08b98d1 commit 010ad8c

File tree

7 files changed

+340
-306
lines changed

7 files changed

+340
-306
lines changed

node.gyp

+2
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@
307307
'src/connection_wrap.cc',
308308
'src/connect_wrap.cc',
309309
'src/env.cc',
310+
'src/exceptions.cc',
310311
'src/fs_event_wrap.cc',
311312
'src/handle_wrap.cc',
312313
'src/js_stream.cc',
@@ -369,6 +370,7 @@
369370
'src/connect_wrap.h',
370371
'src/env.h',
371372
'src/env-inl.h',
373+
'src/exceptions.h',
372374
'src/handle_wrap.h',
373375
'src/js_stream.h',
374376
'src/module_wrap.h',

src/callback_scope.h

+1-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
11
#ifndef SRC_CALLBACK_SCOPE_H_
22
#define SRC_CALLBACK_SCOPE_H_
33

4-
#ifdef _WIN32
5-
# ifndef BUILDING_NODE_EXTENSION
6-
# define NODE_EXTERN __declspec(dllexport)
7-
# else
8-
# define NODE_EXTERN __declspec(dllimport)
9-
# endif
10-
#else
11-
# define NODE_EXTERN /* nothing */
12-
#endif
13-
4+
#include "core.h"
145
#include "v8.h"
156

167
namespace node {

src/core.h

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#ifndef SRC_CORE_H_
2+
#define SRC_CORE_H_
3+
4+
#ifdef _WIN32
5+
# ifndef BUILDING_NODE_EXTENSION
6+
# define NODE_EXTERN __declspec(dllexport)
7+
# else
8+
# define NODE_EXTERN __declspec(dllimport)
9+
# endif
10+
#else
11+
# define NODE_EXTERN /* nothing */
12+
#endif
13+
14+
#define NODE_MAKE_VERSION(major, minor, patch) \
15+
((major) * 0x1000 + (minor) * 0x100 + (patch))
16+
17+
#ifdef __clang__
18+
# define NODE_CLANG_AT_LEAST(major, minor, patch) \
19+
(NODE_MAKE_VERSION(major, minor, patch) <= \
20+
NODE_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__))
21+
#else
22+
# define NODE_CLANG_AT_LEAST(major, minor, patch) (0)
23+
#endif
24+
25+
#ifdef __GNUC__
26+
# define NODE_GNUC_AT_LEAST(major, minor, patch) \
27+
(NODE_MAKE_VERSION(major, minor, patch) <= \
28+
NODE_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__))
29+
#else
30+
# define NODE_GNUC_AT_LEAST(major, minor, patch) (0)
31+
#endif
32+
33+
#if NODE_CLANG_AT_LEAST(2, 9, 0) || NODE_GNUC_AT_LEAST(4, 5, 0)
34+
# define NODE_DEPRECATED(message, declarator) \
35+
__attribute__((deprecated(message))) declarator
36+
#elif defined(_MSC_VER)
37+
# define NODE_DEPRECATED(message, declarator) \
38+
__declspec(deprecated) declarator
39+
#else
40+
# define NODE_DEPRECATED(message, declarator) \
41+
declarator
42+
#endif
43+
44+
#endif // SRC_CORE_H_

src/exceptions.cc

+215
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
#include "node.h"
2+
#include "node_internals.h"
3+
#include "env.h"
4+
#include "env-inl.h"
5+
#include "exceptions.h"
6+
#include "util.h"
7+
#include "util-inl.h"
8+
#include "v8.h"
9+
#include "uv.h"
10+
11+
#include <string.h>
12+
13+
namespace node {
14+
15+
using v8::Exception;
16+
using v8::Integer;
17+
using v8::Isolate;
18+
using v8::Local;
19+
using v8::Message;
20+
using v8::Object;
21+
using v8::String;
22+
using v8::Value;
23+
24+
Local<Value> ErrnoException(Isolate* isolate,
25+
int errorno,
26+
const char *syscall,
27+
const char *msg,
28+
const char *path) {
29+
Environment* env = Environment::GetCurrent(isolate);
30+
31+
Local<Value> e;
32+
Local<String> estring = OneByteString(env->isolate(), errno_string(errorno));
33+
if (msg == nullptr || msg[0] == '\0') {
34+
msg = strerror(errorno);
35+
}
36+
Local<String> message = OneByteString(env->isolate(), msg);
37+
38+
Local<String> cons =
39+
String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
40+
cons = String::Concat(cons, message);
41+
42+
Local<String> path_string;
43+
if (path != nullptr) {
44+
// FIXME(bnoordhuis) It's questionable to interpret the file path as UTF-8.
45+
path_string = String::NewFromUtf8(env->isolate(), path);
46+
}
47+
48+
if (path_string.IsEmpty() == false) {
49+
cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
50+
cons = String::Concat(cons, path_string);
51+
cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
52+
}
53+
e = Exception::Error(cons);
54+
55+
Local<Object> obj = e.As<Object>();
56+
obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno));
57+
obj->Set(env->code_string(), estring);
58+
59+
if (path_string.IsEmpty() == false) {
60+
obj->Set(env->path_string(), path_string);
61+
}
62+
63+
if (syscall != nullptr) {
64+
obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
65+
}
66+
67+
return e;
68+
}
69+
70+
static Local<String> StringFromPath(Isolate* isolate, const char* path) {
71+
#ifdef _WIN32
72+
if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
73+
return String::Concat(FIXED_ONE_BYTE_STRING(isolate, "\\\\"),
74+
String::NewFromUtf8(isolate, path + 8));
75+
} else if (strncmp(path, "\\\\?\\", 4) == 0) {
76+
return String::NewFromUtf8(isolate, path + 4);
77+
}
78+
#endif
79+
80+
return String::NewFromUtf8(isolate, path);
81+
}
82+
83+
84+
Local<Value> UVException(Isolate* isolate,
85+
int errorno,
86+
const char* syscall,
87+
const char* msg,
88+
const char* path) {
89+
return UVException(isolate, errorno, syscall, msg, path, nullptr);
90+
}
91+
92+
93+
Local<Value> UVException(Isolate* isolate,
94+
int errorno,
95+
const char* syscall,
96+
const char* msg,
97+
const char* path,
98+
const char* dest) {
99+
Environment* env = Environment::GetCurrent(isolate);
100+
101+
if (!msg || !msg[0])
102+
msg = uv_strerror(errorno);
103+
104+
Local<String> js_code = OneByteString(isolate, uv_err_name(errorno));
105+
Local<String> js_syscall = OneByteString(isolate, syscall);
106+
Local<String> js_path;
107+
Local<String> js_dest;
108+
109+
Local<String> js_msg = js_code;
110+
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ": "));
111+
js_msg = String::Concat(js_msg, OneByteString(isolate, msg));
112+
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
113+
js_msg = String::Concat(js_msg, js_syscall);
114+
115+
if (path != nullptr) {
116+
js_path = StringFromPath(isolate, path);
117+
118+
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " '"));
119+
js_msg = String::Concat(js_msg, js_path);
120+
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
121+
}
122+
123+
if (dest != nullptr) {
124+
js_dest = StringFromPath(isolate, dest);
125+
126+
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '"));
127+
js_msg = String::Concat(js_msg, js_dest);
128+
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'"));
129+
}
130+
131+
Local<Object> e = Exception::Error(js_msg)->ToObject(isolate);
132+
133+
e->Set(env->errno_string(), Integer::New(isolate, errorno));
134+
e->Set(env->code_string(), js_code);
135+
e->Set(env->syscall_string(), js_syscall);
136+
if (!js_path.IsEmpty())
137+
e->Set(env->path_string(), js_path);
138+
if (!js_dest.IsEmpty())
139+
e->Set(env->dest_string(), js_dest);
140+
141+
return e;
142+
}
143+
144+
#ifdef _WIN32
145+
// Does about the same as strerror(),
146+
// but supports all windows error messages
147+
static const char *winapi_strerror(const int errorno, bool* must_free) {
148+
char *errmsg = nullptr;
149+
150+
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
151+
FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno,
152+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr);
153+
154+
if (errmsg) {
155+
*must_free = true;
156+
157+
// Remove trailing newlines
158+
for (int i = strlen(errmsg) - 1;
159+
i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
160+
errmsg[i] = '\0';
161+
}
162+
163+
return errmsg;
164+
} else {
165+
// FormatMessage failed
166+
*must_free = false;
167+
return "Unknown error";
168+
}
169+
}
170+
171+
172+
Local<Value> WinapiErrnoException(Isolate* isolate,
173+
int errorno,
174+
const char* syscall,
175+
const char* msg,
176+
const char* path) {
177+
Environment* env = Environment::GetCurrent(isolate);
178+
Local<Value> e;
179+
bool must_free = false;
180+
if (!msg || !msg[0]) {
181+
msg = winapi_strerror(errorno, &must_free);
182+
}
183+
Local<String> message = OneByteString(env->isolate(), msg);
184+
185+
if (path) {
186+
Local<String> cons1 =
187+
String::Concat(message, FIXED_ONE_BYTE_STRING(isolate, " '"));
188+
Local<String> cons2 =
189+
String::Concat(cons1, String::NewFromUtf8(isolate, path));
190+
Local<String> cons3 =
191+
String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate, "'"));
192+
e = Exception::Error(cons3);
193+
} else {
194+
e = Exception::Error(message);
195+
}
196+
197+
Local<Object> obj = e.As<Object>();
198+
obj->Set(env->errno_string(), Integer::New(isolate, errorno));
199+
200+
if (path != nullptr) {
201+
obj->Set(env->path_string(), String::NewFromUtf8(isolate, path));
202+
}
203+
204+
if (syscall != nullptr) {
205+
obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
206+
}
207+
208+
if (must_free)
209+
LocalFree((HLOCAL)msg);
210+
211+
return e;
212+
}
213+
#endif
214+
215+
} // namespace node

src/exceptions.h

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#ifndef SRC_EXCEPTIONS_H_
2+
#define SRC_EXCEPTIONS_H_
3+
4+
#include "core.h"
5+
#include "v8.h"
6+
7+
namespace node {
8+
9+
NODE_EXTERN v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate,
10+
int errorno,
11+
const char* syscall = nullptr,
12+
const char* message = nullptr,
13+
const char* path = nullptr);
14+
NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate,
15+
int errorno,
16+
const char* syscall = nullptr,
17+
const char* message = nullptr,
18+
const char* path = nullptr);
19+
NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate,
20+
int errorno,
21+
const char* syscall,
22+
const char* message,
23+
const char* path,
24+
const char* dest);
25+
26+
NODE_DEPRECATED(
27+
"Use ErrnoException(isolate, ...)",
28+
inline v8::Local<v8::Value> ErrnoException(
29+
int errorno,
30+
const char* syscall = nullptr,
31+
const char* message = nullptr,
32+
const char* path = nullptr) {
33+
return ErrnoException(v8::Isolate::GetCurrent(),
34+
errorno,
35+
syscall,
36+
message,
37+
path);
38+
})
39+
40+
inline v8::Local<v8::Value> UVException(int errorno,
41+
const char* syscall = nullptr,
42+
const char* message = nullptr,
43+
const char* path = nullptr) {
44+
return UVException(v8::Isolate::GetCurrent(),
45+
errorno,
46+
syscall,
47+
message,
48+
path);
49+
}
50+
51+
#ifdef _WIN32
52+
NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(
53+
v8::Isolate* isolate,
54+
int errorno,
55+
const char *syscall = nullptr,
56+
const char *msg = "",
57+
const char *path = nullptr);
58+
59+
NODE_DEPRECATED(
60+
"Use WinapiErrnoException(isolate, ...)",
61+
inline v8::Local<v8::Value> WinapiErrnoException(
62+
int errorno,
63+
const char *syscall = nullptr,
64+
const char *msg = "",
65+
const char *path = nullptr) {
66+
return WinapiErrnoException(v8::Isolate::GetCurrent(),
67+
errorno,
68+
syscall,
69+
msg,
70+
path);
71+
})
72+
#endif
73+
74+
} // namespace node
75+
76+
#endif // SRC_EXCEPTIONS_H_

0 commit comments

Comments
 (0)