Skip to content

issue-26 parsing errors should include fields, not just text #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
120 changes: 97 additions & 23 deletions lib/dashdash.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,33 @@ function optionKeyFromName(name) {
return name.replace(/-/g, '_');
}


// ---- Error types
var error_names = [
"NOT_A_NUMBER",
"NOT_AN_INTEGER",
"NOT_A_POSITIVE_INTEGER",
"NOT_A_DATE_FORMAT",
"INVALID_DATE",
"UNKNOWN_OPTION",
"UNKNOWN_OPTION_IN_GROUP",
"ARG_TO_OPTION_NOT_ALLOWED",
"ARG_TO_OPTION_MISSING"
]

var ERRORS = {};
error_names.forEach(function(n) {
ERRORS[n] = n;
})

function augment_error(err, type, data) {
err.type = type;
if (data) {
Object.keys(data).forEach(function (k) {
err[k] = data[k];
})
}
return err;
}

// ---- Option types

Expand All @@ -120,8 +146,12 @@ function parseNumber(option, optstr, arg) {
assert.string(arg, 'arg');
var num = Number(arg);
if (isNaN(num)) {
throw new Error(format('arg for "%s" is not a number: "%s"',
optstr, arg));
throw augment_error(
new Error(format('arg for "%s" is not a number: "%s"',
optstr, arg)),
ERRORS.NOT_A_NUMBER,
{optstr: optstr, arg: arg}
)
}
return num;
}
Expand All @@ -130,8 +160,12 @@ function parseInteger(option, optstr, arg) {
assert.string(arg, 'arg');
var num = Number(arg);
if (!/^[0-9-]+$/.test(arg) || isNaN(num)) {
throw new Error(format('arg for "%s" is not an integer: "%s"',
optstr, arg));
throw augment_error(
new Error(format('arg for "%s" is not an integer: "%s"',
optstr, arg)),
ERRORS.NOT_AN_INTEGER,
{optstr: optstr, arg: arg}
)
}
return num;
}
Expand All @@ -140,8 +174,12 @@ function parsePositiveInteger(option, optstr, arg) {
assert.string(arg, 'arg');
var num = Number(arg);
if (!/^[0-9]+$/.test(arg) || isNaN(num) || num === 0) {
throw new Error(format('arg for "%s" is not a positive integer: "%s"',
optstr, arg));
throw augment_error(
new Error(format('arg for "%s" is not a positive integer: "%s"',
optstr, arg)),
ERRORS.NOT_A_POSITIVE_INTEGER,
{optstr: optstr, arg: arg}
)
}
return num;
}
Expand All @@ -167,12 +205,20 @@ function parseDate(option, optstr, arg) {
// ISO 8601 format
date = new Date(arg);
} else {
throw new Error(format('arg for "%s" is not a valid date format: "%s"',
optstr, arg));
throw augment_error(
new Error(format('arg for "%s" is not a valid date format: "%s"',
optstr, arg)),
ERRORS.NOT_A_DATE_FORMAT,
{optstr: optstr, arg: arg}
)
}
if (date.toString() === 'Invalid Date') {
throw new Error(format('arg for "%s" is an invalid date: "%s"',
optstr, arg));
throw augment_error(
new Error(format('arg for "%s" is an invalid date: "%s"',
optstr, arg)),
ERRORS.INVALID_DATE,
{optstr: optstr, arg: arg}
)
}
return date;
}
Expand Down Expand Up @@ -417,24 +463,36 @@ Parser.prototype.parse = function parse(inputs) {
var option = this.optionFromName[name];
if (!option) {
if (!this.allowUnknown)
throw new Error(format('unknown option: "--%s"', name));
throw augment_error(
new Error(format('unknown option: "--%s"', name)),
ERRORS.UNKNOWN_OPTION,
{optstr: format("--%s", name)}
)
else if (this.interspersed)
_args.push(arg);
else
break outer;
} else {
var takesArg = this.optionTakesArg(option);
if (val !== null && !takesArg) {
throw new Error(format('argument given to "--%s" option '
+ 'that does not take one: "%s"', name, arg));
throw augment_error(
new Error(format('argument given to "--%s" option '
+ 'that does not take one: "%s"', name, arg)),
ERRORS.ARG_TO_OPTION_NOT_ALLOWED,
{optstr: format("--%s", name), arg: arg}
)
}
if (!takesArg) {
addOpt(option, '--'+name, option.key, true, 'argv');
} else if (val !== null) {
addOpt(option, '--'+name, option.key, val, 'argv');
} else if (i + 1 >= args.length) {
throw new Error(format('do not have enough args for "--%s" '
+ 'option', name));
throw augment_error(
new Error(format('do not have enough args for "--%s" '
+ 'option', name)),
ERRORS.ARG_TO_OPTION_MISSING,
{optstr: format("--%s", name)}
)
} else {
addOpt(option, '--'+name, option.key, args[i + 1], 'argv');
i++;
Expand All @@ -457,11 +515,19 @@ Parser.prototype.parse = function parse(inputs) {
} else
break outer;
} else if (arg.length > 2) {
throw new Error(format(
'unknown option: "-%s" in "%s" group',
name, arg));
throw augment_error(
new Error(format(
'unknown option: "-%s" in "%s" group',
name, arg)),
ERRORS.UNKNOWN_OPTION_IN_GROUP,
{optstr: format("-%s", name), group: arg}
)
} else {
throw new Error(format('unknown option: "-%s"', name));
throw augment_error(
new Error(format('unknown option: "-%s"', name)),
ERRORS.UNKNOWN_OPTION,
{optstr: format("-%s", name)}
)
}
} else if (this.optionTakesArg(option)) {
break;
Expand All @@ -482,8 +548,12 @@ Parser.prototype.parse = function parse(inputs) {
break;
} else {
if (i + 1 >= args.length) {
throw new Error(format('do not have enough args '
+ 'for "-%s" option', name));
throw augment_error(
new Error(format('do not have enough args '
+ 'for "-%s" option', name)),
ERRORS.ARG_TO_OPTION_MISSING,
{optstr: format("-%s", name)}
)
}
addOpt(option, '-'+name, option.key, args[i + 1], 'argv');
i++;
Expand Down Expand Up @@ -1051,5 +1121,9 @@ module.exports = {
parseNumber: parseNumber,
parseInteger: parseInteger,
parsePositiveInteger: parsePositiveInteger,
parseDate: parseDate
parseDate: parseDate,

// Export the error types
ERRORS: ERRORS,
augment_error: augment_error
};