Skip to content

Commit

Permalink
feat: introduce custom yargs error object (yargs#765)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: yargs will no longer aggressively supress errors, allowing errors that are not generated internally to bubble.
  • Loading branch information
bcoe committed Feb 26, 2017
1 parent 6ab6a95 commit 8308efa
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,3 +3,4 @@ node_modules/
.nyc_output/
*.swp
test.js
coverage
7 changes: 6 additions & 1 deletion lib/completion.js
Expand Up @@ -44,7 +44,12 @@ module.exports = function (yargs, usage, command) {
var handlers = command.getCommandHandlers()
for (var i = 0, ii = args.length; i < ii; ++i) {
if (handlers[args[i]] && handlers[args[i]].builder) {
return handlers[args[i]].builder(yargs.reset()).argv
const builder = handlers[args[i]].builder
if (typeof builder === 'function') {
const y = yargs.reset()
builder(y)
return y.argv
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion lib/usage.js
Expand Up @@ -3,6 +3,7 @@
const stringWidth = require('string-width')
const objFilter = require('./obj-filter')
const setBlocking = require('set-blocking')
const YError = require('./yerror')

module.exports = function (yargs, y18n) {
const __ = y18n.__
Expand Down Expand Up @@ -50,7 +51,7 @@ module.exports = function (yargs, y18n) {
}
}

err = err || new Error(msg)
err = err || new YError(msg)
if (yargs.getExitProcess()) {
return yargs.exit(1)
} else if (yargs._hasParseCallback()) {
Expand Down
10 changes: 10 additions & 0 deletions lib/yerror.js
@@ -0,0 +1,10 @@
function YError (msg) {
this.name = 'YError'
this.message = msg || 'yargs error'
Error.captureStackTrace(this, YError)
}

YError.prototype = Object.create(Error.prototype)
YError.prototype.constructor = YError

module.exports = YError
2 changes: 0 additions & 2 deletions test/completion.js
Expand Up @@ -97,15 +97,13 @@ describe('Completion', function () {
describe: 'first option'
}
})
.argv
})
.command('cmd2', 'second command', function (subYargs) {
subYargs.options({
opt2: {
describe: 'second option'
}
})
.argv
})
.completion()
.argv
Expand Down
17 changes: 9 additions & 8 deletions test/usage.js
@@ -1,10 +1,11 @@
/* global describe, it, beforeEach */

var checkUsage = require('./helpers/utils').checkOutput
var chalk = require('chalk')
var path = require('path')
var yargs = require('../')
var rebase = require('../yargs').rebase
const checkUsage = require('./helpers/utils').checkOutput
const chalk = require('chalk')
const path = require('path')
const yargs = require('../')
const rebase = require('../yargs').rebase
const YError = require('../lib/yerror')

require('chai').should()

Expand Down Expand Up @@ -482,7 +483,7 @@ describe('usage tests', function () {
describe: 'bar command'
}
}, function (argv) {
throw new Error('blah')
throw new YError('blah')
})
.fail(function (message, error, yargs) {
yargs.showHelp()
Expand Down Expand Up @@ -534,14 +535,14 @@ describe('usage tests', function () {
})
.exitProcess(false)
}, function (argv) {
throw new Error('foo')
throw new YError('foo')
})
.argv
} catch (error) {

}
})
r.logs.should.deep.equal([['Error', 'foo'], 'is triggered last'])
r.logs.should.deep.equal([['YError', 'foo'], 'is triggered last'])
r.should.have.property('exit').and.be.false
})
})
Expand Down
6 changes: 4 additions & 2 deletions yargs.js
Expand Up @@ -8,6 +8,7 @@ const Validation = require('./lib/validation')
const Y18n = require('y18n')
const objFilter = require('./lib/obj-filter')
const setBlocking = require('set-blocking')
const YError = require('./lib/yerror')

var exports = module.exports = Yargs
function Yargs (processArgs, cwd, parentRequire) {
Expand Down Expand Up @@ -867,7 +868,8 @@ function Yargs (processArgs, cwd, parentRequire) {
try {
args = parseArgs(processArgs)
} catch (err) {
usage.fail(err.message, err)
if (err instanceof YError) usage.fail(err.message, err)
else throw err
}

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

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

0 comments on commit 8308efa

Please sign in to comment.