mirror of
https://github.com/flynx/argv.js.git
synced 2025-10-28 18:30:07 +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)
|
||||
- [Installation](#installation)
|
||||
- [Basic usage](#basic-usage)
|
||||
- [Error reporting](#error-reporting)
|
||||
- [XXX add subsections by task](#xxx-add-subsections-by-task)
|
||||
- [Configuration](#configuration)
|
||||
- [Option/command configuration](#optioncommand-configuration)
|
||||
- [`<option>.handler(..)`](#optionhandler)
|
||||
@ -83,10 +85,11 @@ This code is an evolution of that parser.
|
||||
- [Nested parsers](#nested-parsers)
|
||||
- [Components and API](#components-and-api)
|
||||
- [`THEN`, `STOP` and `ERROR`](#then-stop-and-error)
|
||||
- [`ParserError(..)`](#parsererror)
|
||||
- [`Parser(..)`](#parser)
|
||||
- [`<parser>.then(..)`](#parserthen)
|
||||
- [`<parser>.stop(..)`](#parserstop)
|
||||
- [`<parser>.error(..)`](#parsererror)
|
||||
- [`<parser>.error(..)`](#parsererror-1)
|
||||
- [`<parser>.off(..)`](#parseroff)
|
||||
- [`<parser>(..)`](#parser-1)
|
||||
- [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
|
||||
|
||||
```
|
||||
@ -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
|
||||
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(..)`
|
||||
|
||||
Construct a parser instance
|
||||
|
||||
49
argv.js
49
argv.js
@ -37,6 +37,18 @@ module.ERROR =
|
||||
{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...
|
||||
@ -215,20 +227,18 @@ function(name, pre, post){
|
||||
// will think about it when we need this feature more than once...
|
||||
//
|
||||
// XXX should type handlers produce errors???
|
||||
// XXX add support for ParserError exception handling...
|
||||
// XXX should -help work for any command? ..not just nested parsers?
|
||||
// ...should we indicate which thinks have more "-help"??
|
||||
|
||||
|
||||
|
||||
var Parser =
|
||||
module.Parser =
|
||||
object.Constructor('Parser', {
|
||||
// Signature:
|
||||
//
|
||||
// handler(value, ...options)
|
||||
// -> 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: {
|
||||
string: function(v){ return v.toString() },
|
||||
bool: function(v){ return !!v },
|
||||
@ -242,11 +252,11 @@ object.Constructor('Parser', {
|
||||
.map(function(e){ return e.trim() }) },
|
||||
},
|
||||
|
||||
// Signature:
|
||||
//
|
||||
//
|
||||
// handler(value, stored_value, key, ...options)
|
||||
// -> stored_value
|
||||
//
|
||||
// For more info see docs for .typeHandlers
|
||||
valueCollectors: {
|
||||
// format: 'string' | 'string|<separator>'
|
||||
string: function(v, cur, _, sep){
|
||||
@ -290,7 +300,6 @@ object.Constructor('Parser', {
|
||||
// ...
|
||||
// ]
|
||||
//
|
||||
// XXX do we need to output <doc> here???
|
||||
options: function(...prefix){
|
||||
var that = this
|
||||
prefix = prefix.length == 0 ?
|
||||
@ -824,6 +833,9 @@ object.Constructor('Parser', {
|
||||
|
||||
// helpers...
|
||||
var handleError = function(reason, arg, rest){
|
||||
reason = reason instanceof Error ?
|
||||
[reason.name, reason.message].join(': ')
|
||||
: reason
|
||||
parsed.error(reason, arg, rest)
|
||||
parsed.handleErrorExit
|
||||
&& parsed.handleErrorExit(arg, reason) }
|
||||
@ -851,11 +863,24 @@ object.Constructor('Parser', {
|
||||
parsed.printError('value missing:', arg+'=?')
|
||||
return module.ERROR }
|
||||
|
||||
// run handler...
|
||||
var res = parsed.handle(handler, rest, arg, value)
|
||||
try {
|
||||
// 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
|
||||
&& parsed.stop(arg, rest)
|
||||
res instanceof module.ParserError
|
||||
&& handleError(res, arg, rest)
|
||||
res === module.ERROR
|
||||
&& handleError('unknown', arg, rest)
|
||||
return res }
|
||||
@ -924,7 +949,9 @@ object.Constructor('Parser', {
|
||||
var res = runHandler(handler, arg, rest)
|
||||
|
||||
// handle stop conditions...
|
||||
if(res === module.STOP || res === module.ERROR){
|
||||
if(res === module.STOP
|
||||
|| res === module.ERROR
|
||||
|| res instanceof module.ParserError){
|
||||
return nested ?
|
||||
res
|
||||
: parsed }
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ig-argv",
|
||||
"version": "2.4.2",
|
||||
"version": "2.5.0",
|
||||
"description": "simple argv parser",
|
||||
"main": "argv.js",
|
||||
"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 =
|
||||
module.p =
|
||||
argv.Parser({
|
||||
@ -79,6 +83,15 @@ argv.Parser({
|
||||
'-sh': {
|
||||
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({
|
||||
env: 'TEST',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user