-
Notifications
You must be signed in to change notification settings - Fork 30k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
src: move *Exceptions out to separate cc/h
PR-URL: #20789 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
- Loading branch information
1 parent
08b98d1
commit 010ad8c
Showing
7 changed files
with
340 additions
and
306 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef SRC_CORE_H_ | ||
#define SRC_CORE_H_ | ||
|
||
#ifdef _WIN32 | ||
# ifndef BUILDING_NODE_EXTENSION | ||
# define NODE_EXTERN __declspec(dllexport) | ||
# else | ||
# define NODE_EXTERN __declspec(dllimport) | ||
# endif | ||
#else | ||
# define NODE_EXTERN /* nothing */ | ||
#endif | ||
|
||
#define NODE_MAKE_VERSION(major, minor, patch) \ | ||
((major) * 0x1000 + (minor) * 0x100 + (patch)) | ||
|
||
#ifdef __clang__ | ||
# define NODE_CLANG_AT_LEAST(major, minor, patch) \ | ||
(NODE_MAKE_VERSION(major, minor, patch) <= \ | ||
NODE_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)) | ||
#else | ||
# define NODE_CLANG_AT_LEAST(major, minor, patch) (0) | ||
#endif | ||
|
||
#ifdef __GNUC__ | ||
# define NODE_GNUC_AT_LEAST(major, minor, patch) \ | ||
(NODE_MAKE_VERSION(major, minor, patch) <= \ | ||
NODE_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)) | ||
#else | ||
# define NODE_GNUC_AT_LEAST(major, minor, patch) (0) | ||
#endif | ||
|
||
#if NODE_CLANG_AT_LEAST(2, 9, 0) || NODE_GNUC_AT_LEAST(4, 5, 0) | ||
# define NODE_DEPRECATED(message, declarator) \ | ||
__attribute__((deprecated(message))) declarator | ||
#elif defined(_MSC_VER) | ||
# define NODE_DEPRECATED(message, declarator) \ | ||
__declspec(deprecated) declarator | ||
#else | ||
# define NODE_DEPRECATED(message, declarator) \ | ||
declarator | ||
#endif | ||
|
||
#endif // SRC_CORE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
#include "node.h" | ||
#include "node_internals.h" | ||
#include "env.h" | ||
#include "env-inl.h" | ||
#include "exceptions.h" | ||
#include "util.h" | ||
#include "util-inl.h" | ||
#include "v8.h" | ||
#include "uv.h" | ||
|
||
#include <string.h> | ||
|
||
namespace node { | ||
|
||
using v8::Exception; | ||
using v8::Integer; | ||
using v8::Isolate; | ||
using v8::Local; | ||
using v8::Message; | ||
using v8::Object; | ||
using v8::String; | ||
using v8::Value; | ||
|
||
Local<Value> ErrnoException(Isolate* isolate, | ||
int errorno, | ||
const char *syscall, | ||
const char *msg, | ||
const char *path) { | ||
Environment* env = Environment::GetCurrent(isolate); | ||
|
||
Local<Value> e; | ||
Local<String> estring = OneByteString(env->isolate(), errno_string(errorno)); | ||
if (msg == nullptr || msg[0] == '\0') { | ||
msg = strerror(errorno); | ||
} | ||
Local<String> message = OneByteString(env->isolate(), msg); | ||
|
||
Local<String> cons = | ||
String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", ")); | ||
cons = String::Concat(cons, message); | ||
|
||
Local<String> path_string; | ||
if (path != nullptr) { | ||
// FIXME(bnoordhuis) It's questionable to interpret the file path as UTF-8. | ||
path_string = String::NewFromUtf8(env->isolate(), path); | ||
} | ||
|
||
if (path_string.IsEmpty() == false) { | ||
cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), " '")); | ||
cons = String::Concat(cons, path_string); | ||
cons = String::Concat(cons, FIXED_ONE_BYTE_STRING(env->isolate(), "'")); | ||
} | ||
e = Exception::Error(cons); | ||
|
||
Local<Object> obj = e.As<Object>(); | ||
obj->Set(env->errno_string(), Integer::New(env->isolate(), errorno)); | ||
obj->Set(env->code_string(), estring); | ||
|
||
if (path_string.IsEmpty() == false) { | ||
obj->Set(env->path_string(), path_string); | ||
} | ||
|
||
if (syscall != nullptr) { | ||
obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall)); | ||
} | ||
|
||
return e; | ||
} | ||
|
||
static Local<String> StringFromPath(Isolate* isolate, const char* path) { | ||
#ifdef _WIN32 | ||
if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) { | ||
return String::Concat(FIXED_ONE_BYTE_STRING(isolate, "\\\\"), | ||
String::NewFromUtf8(isolate, path + 8)); | ||
} else if (strncmp(path, "\\\\?\\", 4) == 0) { | ||
return String::NewFromUtf8(isolate, path + 4); | ||
} | ||
#endif | ||
|
||
return String::NewFromUtf8(isolate, path); | ||
} | ||
|
||
|
||
Local<Value> UVException(Isolate* isolate, | ||
int errorno, | ||
const char* syscall, | ||
const char* msg, | ||
const char* path) { | ||
return UVException(isolate, errorno, syscall, msg, path, nullptr); | ||
} | ||
|
||
|
||
Local<Value> UVException(Isolate* isolate, | ||
int errorno, | ||
const char* syscall, | ||
const char* msg, | ||
const char* path, | ||
const char* dest) { | ||
Environment* env = Environment::GetCurrent(isolate); | ||
|
||
if (!msg || !msg[0]) | ||
msg = uv_strerror(errorno); | ||
|
||
Local<String> js_code = OneByteString(isolate, uv_err_name(errorno)); | ||
Local<String> js_syscall = OneByteString(isolate, syscall); | ||
Local<String> js_path; | ||
Local<String> js_dest; | ||
|
||
Local<String> js_msg = js_code; | ||
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ": ")); | ||
js_msg = String::Concat(js_msg, OneByteString(isolate, msg)); | ||
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, ", ")); | ||
js_msg = String::Concat(js_msg, js_syscall); | ||
|
||
if (path != nullptr) { | ||
js_path = StringFromPath(isolate, path); | ||
|
||
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " '")); | ||
js_msg = String::Concat(js_msg, js_path); | ||
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'")); | ||
} | ||
|
||
if (dest != nullptr) { | ||
js_dest = StringFromPath(isolate, dest); | ||
|
||
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '")); | ||
js_msg = String::Concat(js_msg, js_dest); | ||
js_msg = String::Concat(js_msg, FIXED_ONE_BYTE_STRING(isolate, "'")); | ||
} | ||
|
||
Local<Object> e = Exception::Error(js_msg)->ToObject(isolate); | ||
|
||
e->Set(env->errno_string(), Integer::New(isolate, errorno)); | ||
e->Set(env->code_string(), js_code); | ||
e->Set(env->syscall_string(), js_syscall); | ||
if (!js_path.IsEmpty()) | ||
e->Set(env->path_string(), js_path); | ||
if (!js_dest.IsEmpty()) | ||
e->Set(env->dest_string(), js_dest); | ||
|
||
return e; | ||
} | ||
|
||
#ifdef _WIN32 | ||
// Does about the same as strerror(), | ||
// but supports all windows error messages | ||
static const char *winapi_strerror(const int errorno, bool* must_free) { | ||
char *errmsg = nullptr; | ||
|
||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | | ||
FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorno, | ||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, nullptr); | ||
|
||
if (errmsg) { | ||
*must_free = true; | ||
|
||
// Remove trailing newlines | ||
for (int i = strlen(errmsg) - 1; | ||
i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) { | ||
errmsg[i] = '\0'; | ||
} | ||
|
||
return errmsg; | ||
} else { | ||
// FormatMessage failed | ||
*must_free = false; | ||
return "Unknown error"; | ||
} | ||
} | ||
|
||
|
||
Local<Value> WinapiErrnoException(Isolate* isolate, | ||
int errorno, | ||
const char* syscall, | ||
const char* msg, | ||
const char* path) { | ||
Environment* env = Environment::GetCurrent(isolate); | ||
Local<Value> e; | ||
bool must_free = false; | ||
if (!msg || !msg[0]) { | ||
msg = winapi_strerror(errorno, &must_free); | ||
} | ||
Local<String> message = OneByteString(env->isolate(), msg); | ||
|
||
if (path) { | ||
Local<String> cons1 = | ||
String::Concat(message, FIXED_ONE_BYTE_STRING(isolate, " '")); | ||
Local<String> cons2 = | ||
String::Concat(cons1, String::NewFromUtf8(isolate, path)); | ||
Local<String> cons3 = | ||
String::Concat(cons2, FIXED_ONE_BYTE_STRING(isolate, "'")); | ||
e = Exception::Error(cons3); | ||
} else { | ||
e = Exception::Error(message); | ||
} | ||
|
||
Local<Object> obj = e.As<Object>(); | ||
obj->Set(env->errno_string(), Integer::New(isolate, errorno)); | ||
|
||
if (path != nullptr) { | ||
obj->Set(env->path_string(), String::NewFromUtf8(isolate, path)); | ||
} | ||
|
||
if (syscall != nullptr) { | ||
obj->Set(env->syscall_string(), OneByteString(isolate, syscall)); | ||
} | ||
|
||
if (must_free) | ||
LocalFree((HLOCAL)msg); | ||
|
||
return e; | ||
} | ||
#endif | ||
|
||
} // namespace node |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#ifndef SRC_EXCEPTIONS_H_ | ||
#define SRC_EXCEPTIONS_H_ | ||
|
||
#include "core.h" | ||
#include "v8.h" | ||
|
||
namespace node { | ||
|
||
NODE_EXTERN v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate, | ||
int errorno, | ||
const char* syscall = nullptr, | ||
const char* message = nullptr, | ||
const char* path = nullptr); | ||
NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate, | ||
int errorno, | ||
const char* syscall = nullptr, | ||
const char* message = nullptr, | ||
const char* path = nullptr); | ||
NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate, | ||
int errorno, | ||
const char* syscall, | ||
const char* message, | ||
const char* path, | ||
const char* dest); | ||
|
||
NODE_DEPRECATED( | ||
"Use ErrnoException(isolate, ...)", | ||
inline v8::Local<v8::Value> ErrnoException( | ||
int errorno, | ||
const char* syscall = nullptr, | ||
const char* message = nullptr, | ||
const char* path = nullptr) { | ||
return ErrnoException(v8::Isolate::GetCurrent(), | ||
errorno, | ||
syscall, | ||
message, | ||
path); | ||
}) | ||
|
||
inline v8::Local<v8::Value> UVException(int errorno, | ||
const char* syscall = nullptr, | ||
const char* message = nullptr, | ||
const char* path = nullptr) { | ||
return UVException(v8::Isolate::GetCurrent(), | ||
errorno, | ||
syscall, | ||
message, | ||
path); | ||
} | ||
|
||
#ifdef _WIN32 | ||
NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException( | ||
v8::Isolate* isolate, | ||
int errorno, | ||
const char *syscall = nullptr, | ||
const char *msg = "", | ||
const char *path = nullptr); | ||
|
||
NODE_DEPRECATED( | ||
"Use WinapiErrnoException(isolate, ...)", | ||
inline v8::Local<v8::Value> WinapiErrnoException( | ||
int errorno, | ||
const char *syscall = nullptr, | ||
const char *msg = "", | ||
const char *path = nullptr) { | ||
return WinapiErrnoException(v8::Isolate::GetCurrent(), | ||
errorno, | ||
syscall, | ||
msg, | ||
path); | ||
}) | ||
#endif | ||
|
||
} // namespace node | ||
|
||
#endif // SRC_EXCEPTIONS_H_ |
Oops, something went wrong.