mirror of
https://github.com/flynx/argv.js.git
synced 2025-10-29 18:50:09 +00:00
added better error reporting and exceptions...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
241c259da0
commit
09be10556f
27
README.md
27
README.md
@ -54,6 +54,8 @@ This code is an evolution of that parser.
|
|||||||
- [Contents](#contents)
|
- [Contents](#contents)
|
||||||
- [Installation](#installation)
|
- [Installation](#installation)
|
||||||
- [Basic usage](#basic-usage)
|
- [Basic usage](#basic-usage)
|
||||||
|
- [Error reporting](#error-reporting)
|
||||||
|
- [XXX add subsections by task](#xxx-add-subsections-by-task)
|
||||||
- [Configuration](#configuration)
|
- [Configuration](#configuration)
|
||||||
- [Option/command configuration](#optioncommand-configuration)
|
- [Option/command configuration](#optioncommand-configuration)
|
||||||
- [`<option>.handler(..)`](#optionhandler)
|
- [`<option>.handler(..)`](#optionhandler)
|
||||||
@ -83,10 +85,11 @@ This code is an evolution of that parser.
|
|||||||
- [Nested parsers](#nested-parsers)
|
- [Nested parsers](#nested-parsers)
|
||||||
- [Components and API](#components-and-api)
|
- [Components and API](#components-and-api)
|
||||||
- [`THEN`, `STOP` and `ERROR`](#then-stop-and-error)
|
- [`THEN`, `STOP` and `ERROR`](#then-stop-and-error)
|
||||||
|
- [`ParserError(..)`](#parsererror)
|
||||||
- [`Parser(..)`](#parser)
|
- [`Parser(..)`](#parser)
|
||||||
- [`<parser>.then(..)`](#parserthen)
|
- [`<parser>.then(..)`](#parserthen)
|
||||||
- [`<parser>.stop(..)`](#parserstop)
|
- [`<parser>.stop(..)`](#parserstop)
|
||||||
- [`<parser>.error(..)`](#parsererror)
|
- [`<parser>.error(..)`](#parsererror-1)
|
||||||
- [`<parser>.off(..)`](#parseroff)
|
- [`<parser>.off(..)`](#parseroff)
|
||||||
- [`<parser>(..)`](#parser-1)
|
- [`<parser>(..)`](#parser-1)
|
||||||
- [Advanced parser API](#advanced-parser-api)
|
- [Advanced parser API](#advanced-parser-api)
|
||||||
@ -228,6 +231,17 @@ $ ./script.js -fb
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Error reporting
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
## XXX add subsections by task
|
||||||
|
|
||||||
|
XXX
|
||||||
|
|
||||||
|
XXX might be a good idea to split out the rest to a INDETAIL.md or similar...
|
||||||
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -687,6 +701,17 @@ Values that if returned by option/command handlers can control the parse flow.
|
|||||||
- `ERROR` – Stop parsing, call `<parser>.error(..)` callbacks and
|
- `ERROR` – Stop parsing, call `<parser>.error(..)` callbacks and
|
||||||
exit with an error.
|
exit with an error.
|
||||||
|
|
||||||
|
### `ParserError(..)`
|
||||||
|
|
||||||
|
A base error constructor, if an instance of `ParseError` is thrown by the
|
||||||
|
handler it has the same effect as returning `ERROR` with one difference being
|
||||||
|
that the error `.name`/`.message` will get printed.
|
||||||
|
|
||||||
|
The following error constructors are also defined:
|
||||||
|
- `ParserTypeError(..)`
|
||||||
|
- `ParserValueError(..)`
|
||||||
|
|
||||||
|
|
||||||
### `Parser(..)`
|
### `Parser(..)`
|
||||||
|
|
||||||
Construct a parser instance
|
Construct a parser instance
|
||||||
|
|||||||
49
argv.js
49
argv.js
@ -37,6 +37,18 @@ module.ERROR =
|
|||||||
{doc: 'option processing error, triggers .error(..) handlers'}
|
{doc: 'option processing error, triggers .error(..) handlers'}
|
||||||
|
|
||||||
|
|
||||||
|
module.ParserError =
|
||||||
|
object.Constructor('ParserError', Error, {
|
||||||
|
// NOTE: I do not get why JavaScript's Error implements this
|
||||||
|
// statically...
|
||||||
|
get name(){
|
||||||
|
return this.constructor.name }, })
|
||||||
|
module.ParserTypeError =
|
||||||
|
object.Constructor('ParserTypeError', module.ParserError, {})
|
||||||
|
module.ParserValueError =
|
||||||
|
object.Constructor('ParserValueError', module.ParserError, {})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Helpers...
|
// Helpers...
|
||||||
@ -215,20 +227,18 @@ function(name, pre, post){
|
|||||||
// will think about it when we need this feature more than once...
|
// will think about it when we need this feature more than once...
|
||||||
//
|
//
|
||||||
// XXX should type handlers produce errors???
|
// XXX should type handlers produce errors???
|
||||||
// XXX add support for ParserError exception handling...
|
|
||||||
// XXX should -help work for any command? ..not just nested parsers?
|
// XXX should -help work for any command? ..not just nested parsers?
|
||||||
// ...should we indicate which thinks have more "-help"??
|
// ...should we indicate which thinks have more "-help"??
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var Parser =
|
var Parser =
|
||||||
module.Parser =
|
module.Parser =
|
||||||
object.Constructor('Parser', {
|
object.Constructor('Parser', {
|
||||||
// Signature:
|
|
||||||
//
|
//
|
||||||
// handler(value, ...options)
|
// handler(value, ...options)
|
||||||
// -> value
|
// -> value
|
||||||
//
|
//
|
||||||
|
// NOTE: options are passed to the definition in the option handler,
|
||||||
|
// i.e. the list of values separated by '|' after the type
|
||||||
|
// definition.
|
||||||
typeHandlers: {
|
typeHandlers: {
|
||||||
string: function(v){ return v.toString() },
|
string: function(v){ return v.toString() },
|
||||||
bool: function(v){ return !!v },
|
bool: function(v){ return !!v },
|
||||||
@ -242,11 +252,11 @@ object.Constructor('Parser', {
|
|||||||
.map(function(e){ return e.trim() }) },
|
.map(function(e){ return e.trim() }) },
|
||||||
},
|
},
|
||||||
|
|
||||||
// Signature:
|
//
|
||||||
//
|
|
||||||
// handler(value, stored_value, key, ...options)
|
// handler(value, stored_value, key, ...options)
|
||||||
// -> stored_value
|
// -> stored_value
|
||||||
//
|
//
|
||||||
|
// For more info see docs for .typeHandlers
|
||||||
valueCollectors: {
|
valueCollectors: {
|
||||||
// format: 'string' | 'string|<separator>'
|
// format: 'string' | 'string|<separator>'
|
||||||
string: function(v, cur, _, sep){
|
string: function(v, cur, _, sep){
|
||||||
@ -290,7 +300,6 @@ object.Constructor('Parser', {
|
|||||||
// ...
|
// ...
|
||||||
// ]
|
// ]
|
||||||
//
|
//
|
||||||
// XXX do we need to output <doc> here???
|
|
||||||
options: function(...prefix){
|
options: function(...prefix){
|
||||||
var that = this
|
var that = this
|
||||||
prefix = prefix.length == 0 ?
|
prefix = prefix.length == 0 ?
|
||||||
@ -824,6 +833,9 @@ object.Constructor('Parser', {
|
|||||||
|
|
||||||
// helpers...
|
// helpers...
|
||||||
var handleError = function(reason, arg, rest){
|
var handleError = function(reason, arg, rest){
|
||||||
|
reason = reason instanceof Error ?
|
||||||
|
[reason.name, reason.message].join(': ')
|
||||||
|
: reason
|
||||||
parsed.error(reason, arg, rest)
|
parsed.error(reason, arg, rest)
|
||||||
parsed.handleErrorExit
|
parsed.handleErrorExit
|
||||||
&& parsed.handleErrorExit(arg, reason) }
|
&& parsed.handleErrorExit(arg, reason) }
|
||||||
@ -851,11 +863,24 @@ object.Constructor('Parser', {
|
|||||||
parsed.printError('value missing:', arg+'=?')
|
parsed.printError('value missing:', arg+'=?')
|
||||||
return module.ERROR }
|
return module.ERROR }
|
||||||
|
|
||||||
// run handler...
|
try {
|
||||||
var res = parsed.handle(handler, rest, arg, value)
|
// run handler...
|
||||||
|
var res = parsed.handle(handler, rest, arg, value)
|
||||||
|
|
||||||
|
} catch(err){
|
||||||
|
// re-throw the error...
|
||||||
|
// NOTE: do not like that this can mask the location of
|
||||||
|
// the original error.
|
||||||
|
if(!(err instanceof module.ParserError)){
|
||||||
|
throw err }
|
||||||
|
res = err }
|
||||||
|
|
||||||
|
// NOTE: we also need to handle the errors passed to us from
|
||||||
|
// nested parsers...
|
||||||
res === module.STOP
|
res === module.STOP
|
||||||
&& parsed.stop(arg, rest)
|
&& parsed.stop(arg, rest)
|
||||||
|
res instanceof module.ParserError
|
||||||
|
&& handleError(res, arg, rest)
|
||||||
res === module.ERROR
|
res === module.ERROR
|
||||||
&& handleError('unknown', arg, rest)
|
&& handleError('unknown', arg, rest)
|
||||||
return res }
|
return res }
|
||||||
@ -924,7 +949,9 @@ object.Constructor('Parser', {
|
|||||||
var res = runHandler(handler, arg, rest)
|
var res = runHandler(handler, arg, rest)
|
||||||
|
|
||||||
// handle stop conditions...
|
// handle stop conditions...
|
||||||
if(res === module.STOP || res === module.ERROR){
|
if(res === module.STOP
|
||||||
|
|| res === module.ERROR
|
||||||
|
|| res instanceof module.ParserError){
|
||||||
return nested ?
|
return nested ?
|
||||||
res
|
res
|
||||||
: parsed }
|
: parsed }
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ig-argv",
|
"name": "ig-argv",
|
||||||
"version": "2.4.2",
|
"version": "2.5.0",
|
||||||
"description": "simple argv parser",
|
"description": "simple argv parser",
|
||||||
"main": "argv.js",
|
"main": "argv.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
13
test.js
13
test.js
@ -17,6 +17,10 @@ var argv = require('./argv')
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
argv.Parser.typeHandlers.error = function(){
|
||||||
|
throw new argv.ParserTypeError('type error') }
|
||||||
|
|
||||||
|
|
||||||
var p =
|
var p =
|
||||||
module.p =
|
module.p =
|
||||||
argv.Parser({
|
argv.Parser({
|
||||||
@ -79,6 +83,15 @@ argv.Parser({
|
|||||||
'-sh': {
|
'-sh': {
|
||||||
doc: 'short option', },
|
doc: 'short option', },
|
||||||
|
|
||||||
|
'-type-error': {
|
||||||
|
doc: 'throw an type error',
|
||||||
|
type: 'error',
|
||||||
|
},
|
||||||
|
'-error': {
|
||||||
|
doc: 'throw an error',
|
||||||
|
handler: function(){
|
||||||
|
throw argv.ParserError('error') }},
|
||||||
|
|
||||||
|
|
||||||
'-test': argv.Parser({
|
'-test': argv.Parser({
|
||||||
env: 'TEST',
|
env: 'TEST',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user