Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -257,6 +257,25 @@ intended as a debugging tool. Some input values can have a significant
performance overhead that can block the event loop. Use this function
with care and never in a hot code path.

## util.getErrorName(code)
<!-- YAML
added: REPLACEME
-->

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

Returns the string name for a numeric error code that comes from a Node.js API.
The mapping between error codes and error names is platform-dependent.
See [Common System Errors][] for the names of common errors.

```js
fs.access('file/that/does/not/exist', (err) => {
const name = util.getErrorName(err.errno);
console.log(name); // ENOENT
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe console.error(name)?

});
```

## util.inherits(constructor, superConstructor)
<!-- YAML
added: v0.3.0
Expand Down Expand Up @@ -1362,6 +1381,7 @@ Deprecated predecessor of `console.log`.
[Customizing `util.inspect` colors]: #util_customizing_util_inspect_colors
[Internationalization]: intl.html
[WHATWG Encoding Standard]: https://encoding.spec.whatwg.org/
[Common System Errors]: errors.html#common_system_errors
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

#common_system_errors -> #errors_common_system_errors )

[constructor]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/constructor
[list of deprecated APIS]: deprecations.html#deprecations_list_of_deprecated_apis
[semantically incompatible]: https://github.com/nodejs/node/issues/4179
7 changes: 4 additions & 3 deletions lib/child_process.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@
'use strict';

const util = require('util');
const { deprecate, convertToValidSignal } = require('internal/util');
const {
deprecate, convertToValidSignal, getErrorName
} = require('internal/util');
const { isUint8Array } = require('internal/util/types');
const { createPromise,
promiseResolve, promiseReject } = process.binding('util');
const debug = util.debuglog('child_process');
const { Buffer } = require('buffer');
const { Pipe, constants: PipeConstants } = process.binding('pipe_wrap');
const errors = require('internal/errors');
const { errname } = process.binding('uv');
const child_process = require('internal/child_process');
const {
_validateStdio,
Expand Down Expand Up @@ -275,7 +276,7 @@ exports.execFile = function(file /*, args, options, callback*/) {
if (!ex) {
ex = new Error('Command failed: ' + cmd + '\n' + stderr);
ex.killed = child.killed || killed;
ex.code = code < 0 ? errname(code) : code;
ex.code = code < 0 ? getErrorName(code) : code;
ex.signal = signal;
}

Expand Down
10 changes: 10 additions & 0 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const {
arrow_message_private_symbol: kArrowMessagePrivateSymbolIndex,
decorated_private_symbol: kDecoratedPrivateSymbolIndex
} = process.binding('util');
const { errmap } = process.binding('uv');

const noCrypto = !process.versions.openssl;

Expand Down Expand Up @@ -213,6 +214,14 @@ function getConstructorOf(obj) {
return null;
}

function getErrorName(code) {
if (errmap.has(code)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should code be type checked at all?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@jasnell Yeah, errname() does CHECK_LT(err, 0), we should probably check for the type and the ranges. Thanks for catching that.

return errmap.get(code)[0];
} else {
return `Unknown system error ${code}`;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Rather than the separate has() and get() calls, perhaps just

function getErrorName(code) {
  const entry = errmap.get(code);
  return entry ? entry[0] : `Unknown system error ${code}`;
}

}

// getConstructorOf is wrapped into this to save iterations
function getIdentificationOf(obj) {
const original = obj;
Expand Down Expand Up @@ -340,6 +349,7 @@ module.exports = {
emitExperimentalWarning,
filterDuplicateStrings,
getConstructorOf,
getErrorName,
getIdentificationOf,
isError,
join,
Expand Down
5 changes: 3 additions & 2 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const errors = require('internal/errors');
const { TextDecoder, TextEncoder } = require('internal/encoding');
const { isBuffer } = require('buffer').Buffer;

const { errname } = process.binding('uv');
const { previewMapIterator, previewSetIterator } = require('internal/v8');

const {
Expand Down Expand Up @@ -56,6 +55,7 @@ const {
const {
customInspectSymbol,
deprecate,
getErrorName,
getIdentificationOf,
isError,
promisify,
Expand Down Expand Up @@ -1062,7 +1062,7 @@ function _errnoException(err, syscall, original) {
throw new errors.RangeError('ERR_OUT_OF_RANGE', 'err',
'a negative integer', err);
}
const name = errname(err);
const name = getErrorName(err);
var message = `${syscall} ${name}`;
if (original)
message += ` ${original}`;
Expand Down Expand Up @@ -1151,6 +1151,7 @@ module.exports = exports = {
debuglog,
deprecate,
format,
getErrorName,
inherits,
inspect,
isArray: Array.isArray,
Expand Down
2 changes: 2 additions & 0 deletions src/uv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ using v8::String;
using v8::Value;


// TODO(joyeecheung): deprecate this function in favor of
// lib/util.getErrorName()
void ErrName(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
int err = args[0]->Int32Value();
Expand Down
5 changes: 3 additions & 2 deletions test/parallel/test-child-process-execfile.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use strict';

const common = require('../common');
const assert = require('assert');
const execFile = require('child_process').execFile;
const uv = process.binding('uv');
const { getErrorName } = require('util');
const fixtures = require('../common/fixtures');

const fixture = fixtures.path('exit.js');
Expand All @@ -26,7 +27,7 @@ const fixture = fixtures.path('exit.js');
const code = -1;
const callback = common.mustCall((err, stdout, stderr) => {
assert.strictEqual(err.toString().trim(), errorString);
assert.strictEqual(err.code, uv.errname(code));
assert.strictEqual(err.code, getErrorName(code));
assert.strictEqual(err.killed, true);
assert.strictEqual(err.signal, null);
assert.strictEqual(err.cmd, process.execPath);
Expand Down
7 changes: 4 additions & 3 deletions test/parallel/test-net-server-listen-handle.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const common = require('../common');
const assert = require('assert');
const net = require('net');
const fs = require('fs');
const uv = process.binding('uv');
const { getErrorName } = require('util');
const { TCP, constants: TCPConstants } = process.binding('tcp_wrap');
const { Pipe, constants: PipeConstants } = process.binding('pipe_wrap');

Expand Down Expand Up @@ -46,9 +46,10 @@ function randomHandle(type) {
handleName = `pipe ${path}`;
}

if (errno < 0) { // uv.errname requires err < 0
assert(errno >= 0, `unable to bind ${handleName}: ${uv.errname(errno)}`);
if (errno < 0) {
assert.fail(`unable to bind ${handleName}: ${getErrorName(errno)}`);
}

if (!common.isWindows) { // fd doesn't work on windows
// err >= 0 but fd = -1, should not happen
assert.notStrictEqual(handle.fd, -1,
Expand Down
16 changes: 10 additions & 6 deletions test/parallel/test-uv-errno.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,31 @@

const common = require('../common');
const assert = require('assert');
const util = require('util');
const uv = process.binding('uv');
const {
getErrorName,
_errnoException
} = require('util');

const uv = process.binding('uv');
const keys = Object.keys(uv);

keys.forEach((key) => {
if (!key.startsWith('UV_'))
return;

assert.doesNotThrow(() => {
const err = util._errnoException(uv[key], 'test');
const err = _errnoException(uv[key], 'test');
const name = uv.errname(uv[key]);
assert.strictEqual(err.code, err.errno);
assert.strictEqual(getErrorName(uv[key]), name);
assert.strictEqual(err.code, name);
assert.strictEqual(err.code, err.errno);
assert.strictEqual(err.message, `test ${name}`);
});
});

['test', {}, []].forEach((key) => {
common.expectsError(
() => util._errnoException(key),
() => _errnoException(key),
{
code: 'ERR_INVALID_ARG_TYPE',
type: TypeError,
Expand All @@ -33,7 +37,7 @@ keys.forEach((key) => {

[0, 1, Infinity, -Infinity, NaN].forEach((key) => {
common.expectsError(
() => util._errnoException(key),
() => _errnoException(key),
{
code: 'ERR_OUT_OF_RANGE',
type: RangeError,
Expand Down
3 changes: 2 additions & 1 deletion test/sequential/test-async-wrap-getasyncid.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const fs = require('fs');
const net = require('net');
const providers = Object.assign({}, process.binding('async_wrap').Providers);
const fixtures = require('../common/fixtures');
const { getErrorName } = require('util');

// Make sure that all Providers are tested.
{
Expand Down Expand Up @@ -204,7 +205,7 @@ if (common.hasCrypto) { // eslint-disable-line crypto-check
// Use a long string to make sure the write happens asynchronously.
const err = handle.writeLatin1String(wreq, 'hi'.repeat(100000));
if (err)
throw new Error(`write failed: ${process.binding('uv').errname(err)}`);
throw new Error(`write failed: ${getErrorName(err)}`);
testInitialized(wreq, 'WriteWrap');
});
req.address = common.localhostIPv4;
Expand Down