src: move *Exceptions out to separate cc/h

PR-URL: https://github.com/nodejs/node/pull/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>
This commit is contained in:
James M Snell 2018-05-16 14:24:25 -07:00
parent c68e6e1f1b
commit 9349e15daa
7 changed files with 340 additions and 306 deletions

View File

@ -309,6 +309,7 @@
'src/connection_wrap.cc',
'src/connect_wrap.cc',
'src/env.cc',
'src/exceptions.cc',
'src/fs_event_wrap.cc',
'src/handle_wrap.cc',
'src/js_stream.cc',
@ -371,6 +372,7 @@
'src/connect_wrap.h',
'src/env.h',
'src/env-inl.h',
'src/exceptions.h',
'src/handle_wrap.h',
'src/js_stream.h',
'src/module_wrap.h',

View File

@ -1,16 +1,7 @@
#ifndef SRC_CALLBACK_SCOPE_H_
#define SRC_CALLBACK_SCOPE_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
#include "core.h"
#include "v8.h"
namespace node {

44
src/core.h Normal file
View File

@ -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_

215
src/exceptions.cc Normal file
View File

@ -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

76
src/exceptions.h Normal file
View File

@ -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_

View File

@ -576,129 +576,6 @@ const char *signo_string(int signo) {
}
}
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;
}
// Look up environment variable unless running as setuid root.
bool SafeGetenv(const char* key, std::string* text) {
#if !defined(__CloudABI__) && !defined(_WIN32)
@ -720,78 +597,6 @@ fail:
}
#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
void* ArrayBufferAllocator::Allocate(size_t size) {
if (zero_fill_field_ || zero_fill_all_buffers)
return UncheckedCalloc(size);

View File

@ -22,16 +22,6 @@
#ifndef SRC_NODE_H_
#define SRC_NODE_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
#ifdef BUILDING_NODE_EXTENSION
# undef BUILDING_V8_SHARED
# undef BUILDING_UV_SHARED
@ -60,40 +50,12 @@
# define SIGKILL 9
#endif
#include "core.h" // NOLINT(build/include_order)
#include "v8.h" // NOLINT(build/include_order)
#include "v8-platform.h" // NOLINT(build/include_order)
#include "node_version.h" // NODE_MODULE_VERSION
#include "callback_scope.h"
#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
#include "exceptions.h"
// Forward-declare libuv loop
struct uv_loop_s;
@ -107,47 +69,6 @@ class TracingController;
// terminally confused when it's done in node_internals.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);
}
/*
* These methods need to be called in a HandleScope.
*
@ -452,26 +373,6 @@ NODE_DEPRECATED("Use DecodeWrite(isolate, ...)",
return DecodeWrite(v8::Isolate::GetCurrent(), buf, buflen, val, encoding);
})
#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
const char *signo_string(int errorno);