Search code examples
javascriptnode.jsnode-modulesnode-commander

How to show custom errors for a node js CLI app made using commander?


So guys this is my code

import chalk from "chalk";
import { Command } from "commander";

const program = new Command();

program
  .name("armath")
  .description(`A cli app to perform arithmetic operations`)
  .option("-a, --add <numbers...>", 'Add two numbers')
  .option("-s, --sub <numbers...>", "Subtract two numbers")
  .option("-m, --multiply <numbers...>", "Multiply two numbers")
  .option("-d, --divide <numbers...>", "Divide two numbers")
  .parse(process.argv);

if (!process.argv.slice(2).length) {
    console.log(chalk.green("Hello World!"));
} else if (program.opts().add) {
    const [num1, num2] = program.opts().add.map(Number);
    const sum = num1 + num2;
    console.log(chalk.green(`${num1} + ${num2} = ${sum}`));
} else if (program.opts().sub) {
    const [num1, num2] = program.opts().sub.map(Number);
    const diff = num1 - num2;
    console.log(chalk.green(`${num1} - ${num2} = ${diff}`));
} else if (program.opts().multiply) {
    const [num1, num2] = program.opts().multiply.map(Number);
    const product = num1 * num2;
    console.log(chalk.green(`${num1} x ${num2} = ${product}`));
} else if (program.opts().divide) {
    const [num1, num2] = program.opts().divide.map(Number);
    if(num2 == 0) {
        console.error(chalk.red(`Error: Division by zero!`));
    } else {
        console.log(chalk.green(`${num1} / ${num2} = ${num1 / num2}`));
    }
} else {
    console.error(chalk.red(`Error: Invalid command! Use --help for usage instructions!`));
}

and now whenever I run node armath.js in my terminal it displays hello world but when I run something random like node armath.js -y it shows error: unknown option '-y' instead of that I want to display something like Error: Invalid command! Use --help for usage instructions!. Can someone help me?

It would be very much helpful if someone can help me! Thanks in advance


Solution

  • There are a few approaches to customising the Commander error handling for different cases.

    1. Add text after errors
    program.showHelpAfterError("Use --help for usage instructions!");
    
    $ node index.mjs --silly
    error: unknown option '--silly'
    Use --help for usage instructions!
    
    1. Customise the error output. This would let you change the text and colour.
    program.configureOutput({
      writeErr: (str) => { 
        str = str.replace('error: ', 'Error: ');
        process.stderr.write(str);
        process.stderr.write("Use --help for usage instructions!\n");
      }
    });
    
    $ node index.mjs --silly
    Error: unknown option '--silly'
    Use --help for usage instructions!
    
    1. You can also make errors throw an exception with a custom code. This isn't such a good match for your situation, so just a brief clue.
    program.exitOverride();
    
    try {
      program.parse();
    } catch (err) {
      // custom processing...
    }
    

    See the project README for more info: https://github.com/tj/commander.js