src: don't abort when c-ares initialization fails
Throw a JS exception instead of aborting so the user at least has a fighting chance of understanding what went wrong. Fixes: https://github.com/nodejs/node/issues/8699 PR-URL: https://github.com/nodejs/node/pull/8710 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com>
This commit is contained in:
parent
a5994f75dc
commit
5cb5b1f8c4
@ -47,6 +47,38 @@ using v8::String;
|
|||||||
using v8::Value;
|
using v8::Value;
|
||||||
|
|
||||||
|
|
||||||
|
inline const char* ToErrorCodeString(int status) {
|
||||||
|
switch (status) {
|
||||||
|
#define V(code) case ARES_##code: return #code;
|
||||||
|
V(EADDRGETNETWORKPARAMS)
|
||||||
|
V(EBADFAMILY)
|
||||||
|
V(EBADFLAGS)
|
||||||
|
V(EBADHINTS)
|
||||||
|
V(EBADNAME)
|
||||||
|
V(EBADQUERY)
|
||||||
|
V(EBADRESP)
|
||||||
|
V(EBADSTR)
|
||||||
|
V(ECANCELLED)
|
||||||
|
V(ECONNREFUSED)
|
||||||
|
V(EDESTRUCTION)
|
||||||
|
V(EFILE)
|
||||||
|
V(EFORMERR)
|
||||||
|
V(ELOADIPHLPAPI)
|
||||||
|
V(ENODATA)
|
||||||
|
V(ENOMEM)
|
||||||
|
V(ENONAME)
|
||||||
|
V(ENOTFOUND)
|
||||||
|
V(ENOTIMP)
|
||||||
|
V(ENOTINITIALIZED)
|
||||||
|
V(EOF)
|
||||||
|
V(EREFUSED)
|
||||||
|
V(ESERVFAIL)
|
||||||
|
V(ETIMEOUT)
|
||||||
|
#undef V
|
||||||
|
}
|
||||||
|
return "UNKNOWN_ARES_ERROR";
|
||||||
|
}
|
||||||
|
|
||||||
class GetAddrInfoReqWrap : public ReqWrap<uv_getaddrinfo_t> {
|
class GetAddrInfoReqWrap : public ReqWrap<uv_getaddrinfo_t> {
|
||||||
public:
|
public:
|
||||||
GetAddrInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);
|
GetAddrInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);
|
||||||
@ -330,41 +362,8 @@ class QueryWrap : public AsyncWrap {
|
|||||||
CHECK_NE(status, ARES_SUCCESS);
|
CHECK_NE(status, ARES_SUCCESS);
|
||||||
HandleScope handle_scope(env()->isolate());
|
HandleScope handle_scope(env()->isolate());
|
||||||
Context::Scope context_scope(env()->context());
|
Context::Scope context_scope(env()->context());
|
||||||
Local<Value> arg;
|
const char* code = ToErrorCodeString(status);
|
||||||
switch (status) {
|
Local<Value> arg = OneByteString(env()->isolate(), code);
|
||||||
#define V(code) \
|
|
||||||
case ARES_ ## code: \
|
|
||||||
arg = FIXED_ONE_BYTE_STRING(env()->isolate(), #code); \
|
|
||||||
break;
|
|
||||||
V(ENODATA)
|
|
||||||
V(EFORMERR)
|
|
||||||
V(ESERVFAIL)
|
|
||||||
V(ENOTFOUND)
|
|
||||||
V(ENOTIMP)
|
|
||||||
V(EREFUSED)
|
|
||||||
V(EBADQUERY)
|
|
||||||
V(EBADNAME)
|
|
||||||
V(EBADFAMILY)
|
|
||||||
V(EBADRESP)
|
|
||||||
V(ECONNREFUSED)
|
|
||||||
V(ETIMEOUT)
|
|
||||||
V(EOF)
|
|
||||||
V(EFILE)
|
|
||||||
V(ENOMEM)
|
|
||||||
V(EDESTRUCTION)
|
|
||||||
V(EBADSTR)
|
|
||||||
V(EBADFLAGS)
|
|
||||||
V(ENONAME)
|
|
||||||
V(EBADHINTS)
|
|
||||||
V(ENOTINITIALIZED)
|
|
||||||
V(ELOADIPHLPAPI)
|
|
||||||
V(EADDRGETNETWORKPARAMS)
|
|
||||||
V(ECANCELLED)
|
|
||||||
#undef V
|
|
||||||
default:
|
|
||||||
arg = FIXED_ONE_BYTE_STRING(env()->isolate(), "UNKNOWN_ARES_ERROR");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
MakeCallback(env()->oncomplete_string(), 1, &arg);
|
MakeCallback(env()->oncomplete_string(), 1, &arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1311,7 +1310,8 @@ static void Initialize(Local<Object> target,
|
|||||||
Environment* env = Environment::GetCurrent(context);
|
Environment* env = Environment::GetCurrent(context);
|
||||||
|
|
||||||
int r = ares_library_init(ARES_LIB_INIT_ALL);
|
int r = ares_library_init(ARES_LIB_INIT_ALL);
|
||||||
CHECK_EQ(r, ARES_SUCCESS);
|
if (r != ARES_SUCCESS)
|
||||||
|
return env->ThrowError(ToErrorCodeString(r));
|
||||||
|
|
||||||
struct ares_options options;
|
struct ares_options options;
|
||||||
memset(&options, 0, sizeof(options));
|
memset(&options, 0, sizeof(options));
|
||||||
@ -1323,7 +1323,10 @@ static void Initialize(Local<Object> target,
|
|||||||
r = ares_init_options(env->cares_channel_ptr(),
|
r = ares_init_options(env->cares_channel_ptr(),
|
||||||
&options,
|
&options,
|
||||||
ARES_OPT_FLAGS | ARES_OPT_SOCK_STATE_CB);
|
ARES_OPT_FLAGS | ARES_OPT_SOCK_STATE_CB);
|
||||||
CHECK_EQ(r, ARES_SUCCESS);
|
if (r != ARES_SUCCESS) {
|
||||||
|
ares_library_cleanup();
|
||||||
|
return env->ThrowError(ToErrorCodeString(r));
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the timeout timer. The timer won't be started until the */
|
/* Initialize the timeout timer. The timer won't be started until the */
|
||||||
/* first socket is opened. */
|
/* first socket is opened. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user