From 5cb5b1f8c4b67d31d977cee66cb07adaa4acb25f Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 22 Sep 2016 10:45:36 +0200 Subject: [PATCH] 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 Reviewed-By: Franziska Hinkelmann Reviewed-By: Ilkka Myller --- src/cares_wrap.cc | 77 ++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 44048c5dc7..3aab61e1b3 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -47,6 +47,38 @@ using v8::String; 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 { public: GetAddrInfoReqWrap(Environment* env, Local req_wrap_obj); @@ -330,41 +362,8 @@ class QueryWrap : public AsyncWrap { CHECK_NE(status, ARES_SUCCESS); HandleScope handle_scope(env()->isolate()); Context::Scope context_scope(env()->context()); - Local arg; - switch (status) { -#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; - } + const char* code = ToErrorCodeString(status); + Local arg = OneByteString(env()->isolate(), code); MakeCallback(env()->oncomplete_string(), 1, &arg); } @@ -1311,7 +1310,8 @@ static void Initialize(Local target, Environment* env = Environment::GetCurrent(context); 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; memset(&options, 0, sizeof(options)); @@ -1323,7 +1323,10 @@ static void Initialize(Local target, r = ares_init_options(env->cares_channel_ptr(), &options, 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 */ /* first socket is opened. */