Skip to content

Commit

Permalink
feat: do not print errors returned from yargs (#300)
Browse files Browse the repository at this point in the history
  • Loading branch information
hongaar authored Sep 8, 2021
1 parent 854e91f commit 90712a9
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 5 deletions.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ intuitive to work with.
- [Getting started](#getting-started)
- [Installation](#installation)
- [Simple example](#simple-example)
- [Error handling](#error-handling)
- [REPL example](#repl-example)
- [Prompt](#prompt)
- [TypeScript](#typescript)
Expand Down Expand Up @@ -124,6 +125,58 @@ Options:
_ℹ You see `bin.js` here instead of `foo.ts` because we're running the program
with `ts-node`._

### Error handling

We first create a new program called `cat.ts` which is a simple version of the
`cat` program we all know:

```ts
import { readFileSync } from 'fs'
import { program, command } from 'bandersnatch'

const cat = command('cat')
.description('Concatenate files')
.argument('files', { variadic: true })
.action(({ files }) =>
console.log(
files.reduce((str, file) => str + readFileSync(file, 'utf8'), '')
)
)

program().default(cat).run()
```

Now try your program by running it:

```
$ ts-node cat.ts somefile
contents of somefile
```

However, when `somefile` doesn't exist, we get are faced with an ugly unhandled
promise rejection warning/error (depending on the Node.js version you're using).

Let's fix that:

```diff
-program().default(cat).run()
+program()
+ .default(cat)
+ .run()
+ .catch((err) => {
+ console.error(`There was a problem running this command:\n${String(err)}`)
+ process.exit(1)
+ })
```

Which will yield:

```
$ ts-node cat.ts somefile
There was a problem running this command:
Error: ENOENT: no such file or directory, open 'somefile'
```

### REPL example

A program can also show an interactive
Expand Down
19 changes: 19 additions & 0 deletions examples/cat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { readFileSync } from 'fs'
import { command, program } from '../src'

const cat = command('cat')
.description('Concatenate files')
.argument('files', { variadic: true })
.action(({ files }) =>
console.log(
files.reduce((str, file) => str + readFileSync(file, 'utf8'), '')
)
)

program()
.default(cat)
.run()
.catch((err) => {
console.error(`There was a problem running this command:\n${String(err)}`)
process.exit(1)
})
2 changes: 1 addition & 1 deletion examples/errors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { program, command } from '../src'
import { command, program } from '../src'

const app = program()

Expand Down
14 changes: 10 additions & 4 deletions src/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ type ProgramOptions = {

/**
* Specifies whether to add a default behaviour for an `exit` command.
*
*
* Takes a boolean or a function argument:
* - `false` installs no handler
* - `true` will install the default handler
* - a given function will be installed as the handler
*
*
* Defaults to `() => process.exit()`.
*/
exit?: boolean | (() => void)
Expand Down Expand Up @@ -99,7 +99,10 @@ export class Program extends (EventEmitter as new () => TypedEventEmitter<Events
}

// Set default exit handler
if (this.options.exit === true || typeof this.options.exit === 'undefined') {
if (
this.options.exit === true ||
typeof this.options.exit === 'undefined'
) {
this.options.exit = () => process.exit()
}

Expand Down Expand Up @@ -217,9 +220,12 @@ export class Program extends (EventEmitter as new () => TypedEventEmitter<Events
* From the yargs docs:
* > Populated if any validation errors raised while parsing.
* http://yargs.js.org/docs/#api-parseargs-context-parsecallback
* This seems to be incorrect though, and err is populated when any
* error is thrown inside the command handler.
*/
if (err) {
console.error(err)
// Ignore err value, which encourages users to deliberately handle
// error conditions in their programs.
}

if (isPromise(argv.__promise)) {
Expand Down

0 comments on commit 90712a9

Please sign in to comment.