Skip to content

Commit

Permalink
Avoid relying on Node’s internals (#125)
Browse files Browse the repository at this point in the history
`process.binding()` is not a public API, and should
not be used.

Luckily, Node recently introduced an API that does
exactly what execa needs:
nodejs/node#18186

So use that instead and keep the old path as a fallback.
  • Loading branch information
addaleax authored and sindresorhus committed Feb 2, 2018
1 parent b019895 commit 51a45df
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 23 deletions.
38 changes: 20 additions & 18 deletions lib/errname.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
'use strict';
// The Node team wants to deprecate `process.bind(...)`.
// https://github.com/nodejs/node/pull/2768
//
// However, we need the 'uv' binding for errname support.
// This is a defensive wrapper around it so `execa` will not fail entirely if it stops working someday.
//
// If this ever stops working. See: https://github.com/sindresorhus/execa/issues/31#issuecomment-215939939 for another possible solution.
// Older verions of Node might not have `util.getSystemErrorName()`.
// In that case, fall back to a deprecated internal.
const util = require('util');

let uv;

try {
uv = process.binding('uv');
if (typeof util.getSystemErrorName === 'function') {
module.exports = util.getSystemErrorName;
} else {
try {
uv = process.binding('uv');

if (typeof uv.errname !== 'function') {
throw new TypeError('uv.errname is not a function');
if (typeof uv.errname !== 'function') {
throw new TypeError('uv.errname is not a function');
}
} catch (err) {
console.error('execa/lib/errname: unable to establish process.binding(\'uv\')', err);
uv = null;
}
} catch (err) {
console.error('execa/lib/errname: unable to establish process.binding(\'uv\')', err);
uv = null;

module.exports = code => errname(uv, code);
}

// Used for testing the fallback behavior
module.exports.__test__ = errname;

function errname(uv, code) {
if (uv) {
return uv.errname(code);
Expand All @@ -31,7 +37,3 @@ function errname(uv, code) {
return `Unknown system error ${code}`;
}

module.exports = code => errname(uv, code);

// Used for testing the fallback behavior
module.exports.__test__ = errname;
9 changes: 4 additions & 5 deletions test/errname.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ const fallback = code => errname.__test__(null, code);
function makeTests(name, m, expected) {
test(`${name}: >=0 exit codes`, t => {
// Throws >= 0
t.throws(() => m(0), /err >= 0/);
t.throws(() => m(1), /err >= 0/);
t.throws(() => m('2'), /err >= 0/);
t.throws(() => m('foo'), /err >= 0/);
t.throws(() => m(0), /err >= 0|It must be a negative integer/);
t.throws(() => m(1), /err >= 0|It must be a negative integer/);
t.throws(() => m('2'), /err >= 0|must be of type number/);
t.throws(() => m('foo'), /err >= 0|must be of type number/);
});

test(`${name}: negative exit codes`, t => {
t.is(m(-2), expected);
t.is(m('-2'), expected);
});
}

Expand Down

0 comments on commit 51a45df

Please sign in to comment.