Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,26 @@ fs.access('file/that/does/not/exist', (err) => {
});
```

## `util.getSystemErrorMessage(err)`

<!-- YAML
added: REPLACEME
-->

* `err` {number}
* Returns: {string}

Returns the string message for a numeric error code that comes from a Node.js
API.
The mapping between error codes and string messages is platform-dependent.

```js
fs.access('file/that/does/not/exist', (err) => {
const name = util.getSystemErrorMessage(err.errno);
console.error(name); // no such file or directory
});
```

## `util.inherits(constructor, superConstructor)`

<!-- YAML
Expand Down
5 changes: 5 additions & 0 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,10 @@ function getCWDURL() {
return cachedURL;
}

function getSystemErrorMessage(err) {
return lazyUv().getErrorMessage(err);
}

function getSystemErrorName(err) {
const entry = uvErrmapGet(err);
return entry ? entry[0] : `Unknown system error ${err}`;
Expand Down Expand Up @@ -880,6 +884,7 @@ module.exports = {
getStructuredStack,
getSystemErrorMap,
getSystemErrorName,
getSystemErrorMessage,
guessHandleType,
isError,
isUnderNodeModules,
Expand Down
14 changes: 14 additions & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ const {
deprecate,
getSystemErrorMap,
getSystemErrorName: internalErrorName,
getSystemErrorMessage: internalErrorMessage,
promisify,
defineLazyProperties,
} = require('internal/util');
Expand Down Expand Up @@ -269,6 +270,18 @@ function callbackify(original) {
return callbackified;
}

/**
* @param {number} err
* @returns {string}
*/
function getSystemErrorMessage(err) {
validateNumber(err, 'err');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to call validateNumber since in the next line we check for SafeNumber?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (err >= 0 || !NumberIsSafeInteger(err)) {
throw new ERR_OUT_OF_RANGE('err', 'a negative integer', err);
}
return internalErrorMessage(err);
}

/**
* @param {number} err
* @returns {string}
Expand Down Expand Up @@ -343,6 +356,7 @@ module.exports = {
getCallSite,
getSystemErrorMap,
getSystemErrorName,
getSystemErrorMessage,
inherits,
inspect,
isArray: deprecate(ArrayIsArray,
Expand Down
14 changes: 12 additions & 2 deletions src/uv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ using v8::ReadOnly;
using v8::String;
using v8::Value;

void GetErrMessage(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
int err = args[0].As<v8::Int32>()->Value();
CHECK_LT(err, 0);
char message[50];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 50? Can you add a comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment?

uv_strerror_r(err, message, sizeof(message));
args.GetReturnValue().Set(OneByteString(env->isolate(), message));
}

void ErrName(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
if (env->options()->pending_deprecation && env->EmitErrNameWarning()) {
Expand All @@ -70,8 +79,7 @@ void ErrName(const FunctionCallbackInfo<Value>& args) {
"DEP0119").IsNothing())
return;
}
int err;
if (!args[0]->Int32Value(env->context()).To(&err)) return;
int err = args[0].As<v8::Int32>()->Value();
CHECK_LT(err, 0);
char name[50];
uv_err_name_r(err, name, sizeof(name));
Expand Down Expand Up @@ -128,11 +136,13 @@ void Initialize(Local<Object> target,
}

SetMethod(context, target, "getErrorMap", GetErrMap);
SetMethod(context, target, "getErrorMessage", GetErrMessage);
}

void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(ErrName);
registry->Register(GetErrMap);
registry->Register(GetErrMessage);
}
} // namespace uv
} // namespace node
Expand Down
5 changes: 5 additions & 0 deletions test/parallel/test-uv-errno.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const common = require('../common');
const assert = require('assert');
const {
getSystemErrorName,
getSystemErrorMessage,
_errnoException
} = require('util');

Expand All @@ -13,6 +14,7 @@ const uv = internalBinding('uv');
const keys = Object.keys(uv);

assert.strictEqual(uv.errname(-111111), 'Unknown system error -111111');
assert.strictEqual(uv.getErrorMessage(-111111), 'Unknown system error -111111');

keys.forEach((key) => {
if (!key.startsWith('UV_'))
Expand All @@ -21,6 +23,8 @@ keys.forEach((key) => {
const err = _errnoException(uv[key], 'test');
const name = uv.errname(uv[key]);
assert.strictEqual(getSystemErrorName(uv[key]), name);
assert.notStrictEqual(getSystemErrorMessage(uv[key]),
`Unknown system error ${key}`);
assert.strictEqual(err.code, name);
assert.strictEqual(err.code, getSystemErrorName(err.errno));
assert.strictEqual(err.message, `test ${name}`);
Expand Down Expand Up @@ -53,3 +57,4 @@ function runTest(fn) {

runTest(_errnoException);
runTest(getSystemErrorName);
runTest(getSystemErrorMessage);
Loading