Skip to content

Commit 8308efa

Browse files
committed
feat: introduce custom yargs error object (#765)
BREAKING CHANGE: yargs will no longer aggressively supress errors, allowing errors that are not generated internally to bubble.
1 parent 6ab6a95 commit 8308efa

File tree

7 files changed

+32
-14
lines changed

7 files changed

+32
-14
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ node_modules/
33
.nyc_output/
44
*.swp
55
test.js
6+
coverage

lib/completion.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ module.exports = function (yargs, usage, command) {
4444
var handlers = command.getCommandHandlers()
4545
for (var i = 0, ii = args.length; i < ii; ++i) {
4646
if (handlers[args[i]] && handlers[args[i]].builder) {
47-
return handlers[args[i]].builder(yargs.reset()).argv
47+
const builder = handlers[args[i]].builder
48+
if (typeof builder === 'function') {
49+
const y = yargs.reset()
50+
builder(y)
51+
return y.argv
52+
}
4853
}
4954
}
5055

lib/usage.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const stringWidth = require('string-width')
44
const objFilter = require('./obj-filter')
55
const setBlocking = require('set-blocking')
6+
const YError = require('./yerror')
67

78
module.exports = function (yargs, y18n) {
89
const __ = y18n.__
@@ -50,7 +51,7 @@ module.exports = function (yargs, y18n) {
5051
}
5152
}
5253

53-
err = err || new Error(msg)
54+
err = err || new YError(msg)
5455
if (yargs.getExitProcess()) {
5556
return yargs.exit(1)
5657
} else if (yargs._hasParseCallback()) {

lib/yerror.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function YError (msg) {
2+
this.name = 'YError'
3+
this.message = msg || 'yargs error'
4+
Error.captureStackTrace(this, YError)
5+
}
6+
7+
YError.prototype = Object.create(Error.prototype)
8+
YError.prototype.constructor = YError
9+
10+
module.exports = YError

test/completion.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,13 @@ describe('Completion', function () {
9797
describe: 'first option'
9898
}
9999
})
100-
.argv
101100
})
102101
.command('cmd2', 'second command', function (subYargs) {
103102
subYargs.options({
104103
opt2: {
105104
describe: 'second option'
106105
}
107106
})
108-
.argv
109107
})
110108
.completion()
111109
.argv

test/usage.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
/* global describe, it, beforeEach */
22

3-
var checkUsage = require('./helpers/utils').checkOutput
4-
var chalk = require('chalk')
5-
var path = require('path')
6-
var yargs = require('../')
7-
var rebase = require('../yargs').rebase
3+
const checkUsage = require('./helpers/utils').checkOutput
4+
const chalk = require('chalk')
5+
const path = require('path')
6+
const yargs = require('../')
7+
const rebase = require('../yargs').rebase
8+
const YError = require('../lib/yerror')
89

910
require('chai').should()
1011

@@ -482,7 +483,7 @@ describe('usage tests', function () {
482483
describe: 'bar command'
483484
}
484485
}, function (argv) {
485-
throw new Error('blah')
486+
throw new YError('blah')
486487
})
487488
.fail(function (message, error, yargs) {
488489
yargs.showHelp()
@@ -534,14 +535,14 @@ describe('usage tests', function () {
534535
})
535536
.exitProcess(false)
536537
}, function (argv) {
537-
throw new Error('foo')
538+
throw new YError('foo')
538539
})
539540
.argv
540541
} catch (error) {
541542

542543
}
543544
})
544-
r.logs.should.deep.equal([['Error', 'foo'], 'is triggered last'])
545+
r.logs.should.deep.equal([['YError', 'foo'], 'is triggered last'])
545546
r.should.have.property('exit').and.be.false
546547
})
547548
})

yargs.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const Validation = require('./lib/validation')
88
const Y18n = require('y18n')
99
const objFilter = require('./lib/obj-filter')
1010
const setBlocking = require('set-blocking')
11+
const YError = require('./lib/yerror')
1112

1213
var exports = module.exports = Yargs
1314
function Yargs (processArgs, cwd, parentRequire) {
@@ -867,7 +868,8 @@ function Yargs (processArgs, cwd, parentRequire) {
867868
try {
868869
args = parseArgs(processArgs)
869870
} catch (err) {
870-
usage.fail(err.message, err)
871+
if (err instanceof YError) usage.fail(err.message, err)
872+
else throw err
871873
}
872874

873875
return args
@@ -993,7 +995,7 @@ function Yargs (processArgs, cwd, parentRequire) {
993995
// If the help or version options where used and exitProcess is false,
994996
// or if explicitly skipped, we won't run validations
995997
if (!skipValidation) {
996-
if (parsed.error) throw parsed.error
998+
if (parsed.error) throw new YError(parsed.error.message)
997999

9981000
// if we're executed via bash completion, don't
9991001
// bother with validation.

0 commit comments

Comments
 (0)