diff --git a/lib/os.js b/lib/os.js index 6af5d15cbc4..7c07a5b0d38 100644 --- a/lib/os.js +++ b/lib/os.js @@ -27,21 +27,43 @@ const { deprecate } = require('internal/util'); const { getCIDRSuffix } = require('internal/os'); const isWindows = process.platform === 'win32'; +const errors = require('internal/errors'); + const { getCPUs, getFreeMem, - getHomeDirectory, - getHostname, - getInterfaceAddresses, + getHomeDirectory: _getHomeDirectory, + getHostname: _getHostname, + getInterfaceAddresses: _getInterfaceAddresses, getLoadAvg, - getOSRelease, - getOSType, + getOSRelease: _getOSRelease, + getOSType: _getOSType, getTotalMem, - getUserInfo, + getUserInfo: _getUserInfo, getUptime, isBigEndian } = process.binding('os'); +function getCheckedFunction(fn) { + return function checkError(...args) { + const ctx = {}; + const ret = fn(...args, ctx); + if (ret === undefined) { + const err = new errors.SystemError(ctx); + Error.captureStackTrace(err, checkError); + throw err; + } + return ret; + }; +} + +const getHomeDirectory = getCheckedFunction(_getHomeDirectory); +const getHostname = getCheckedFunction(_getHostname); +const getInterfaceAddresses = getCheckedFunction(_getInterfaceAddresses); +const getOSRelease = getCheckedFunction(_getOSRelease); +const getOSType = getCheckedFunction(_getOSType); +const getUserInfo = getCheckedFunction(_getUserInfo); + getFreeMem[Symbol.toPrimitive] = () => getFreeMem(); getHostname[Symbol.toPrimitive] = () => getHostname(); getHomeDirectory[Symbol.toPrimitive] = () => getHomeDirectory(); diff --git a/src/node_os.cc b/src/node_os.cc index f09cd6fa5a0..c57841ca9ec 100644 --- a/src/node_os.cc +++ b/src/node_os.cc @@ -72,7 +72,9 @@ static void GetHostname(const FunctionCallbackInfo& args) { #else // __MINGW32__ int errorno = WSAGetLastError(); #endif // __POSIX__ - return env->ThrowErrnoException(errorno, "gethostname"); + CHECK_GE(args.Length(), 1); + env->CollectExceptionInfo(args[args.Length() - 1], errorno, "gethostname"); + return args.GetReturnValue().SetUndefined(); } buf[sizeof(buf) - 1] = '\0'; @@ -87,7 +89,9 @@ static void GetOSType(const FunctionCallbackInfo& args) { #ifdef __POSIX__ struct utsname info; if (uname(&info) < 0) { - return env->ThrowErrnoException(errno, "uname"); + CHECK_GE(args.Length(), 1); + env->CollectExceptionInfo(args[args.Length() - 1], errno, "uname"); + return args.GetReturnValue().SetUndefined(); } rval = info.sysname; #else // __MINGW32__ @@ -105,7 +109,9 @@ static void GetOSRelease(const FunctionCallbackInfo& args) { #ifdef __POSIX__ struct utsname info; if (uname(&info) < 0) { - return env->ThrowErrnoException(errno, "uname"); + CHECK_GE(args.Length(), 1); + env->CollectExceptionInfo(args[args.Length() - 1], errno, "uname"); + return args.GetReturnValue().SetUndefined(); } # ifdef _AIX char release[256]; @@ -242,7 +248,10 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo& args) { if (err == UV_ENOSYS) { return args.GetReturnValue().Set(ret); } else if (err) { - return env->ThrowUVException(err, "uv_interface_addresses"); + CHECK_GE(args.Length(), 1); + env->CollectUVExceptionInfo(args[args.Length() - 1], errno, + "uv_interface_addresses"); + return args.GetReturnValue().SetUndefined(); } for (i = 0; i < count; i++) { @@ -319,7 +328,9 @@ static void GetHomeDirectory(const FunctionCallbackInfo& args) { const int err = uv_os_homedir(buf, &len); if (err) { - return env->ThrowUVException(err, "uv_os_homedir"); + CHECK_GE(args.Length(), 1); + env->CollectUVExceptionInfo(args[args.Length() - 1], err, "uv_os_homedir"); + return args.GetReturnValue().SetUndefined(); } Local home = String::NewFromUtf8(env->isolate(), @@ -351,7 +362,10 @@ static void GetUserInfo(const FunctionCallbackInfo& args) { const int err = uv_os_get_passwd(&pwd); if (err) { - return env->ThrowUVException(err, "uv_os_get_passwd"); + CHECK_GE(args.Length(), 2); + env->CollectUVExceptionInfo(args[args.Length() - 1], err, + "uv_os_get_passwd"); + return args.GetReturnValue().SetUndefined(); } Local error;