Module: CLI::Kit

Defined in:
lib/cli/kit.rb,
lib/cli/kit/ini.rb,
lib/cli/kit/args.rb,
lib/cli/kit/opts.rb,
lib/cli/kit/util.rb,
lib/cli/kit/config.rb,
lib/cli/kit/logger.rb,
lib/cli/kit/system.rb,
lib/cli/kit/support.rb,
lib/cli/kit/version.rb,
lib/cli/kit/executor.rb,
lib/cli/kit/resolver.rb,
lib/cli/kit/parse_args.rb,
lib/cli/kit/args/parser.rb,
lib/cli/kit/levenshtein.rb,
lib/cli/kit/base_command.rb,
lib/cli/kit/command_help.rb,
lib/cli/kit/error_handler.rb,
lib/cli/kit/args/tokenizer.rb,
lib/cli/kit/args/definition.rb,
lib/cli/kit/args/evaluation.rb,
lib/cli/kit/args/parser/node.rb,
lib/cli/kit/command_registry.rb,
lib/cli/kit/support/test_helper.rb,
lib/cli/kit/support/test_helper.rb

Defined Under Namespace

Modules: Args, CommandHelp, Levenshtein, ParseArgs, Support, System, Util Classes: Abort, AbortSilent, BaseCommand, Bug, BugSilent, CommandRegistry, Config, ErrorHandler, Executor, Ini, Logger, Opts, Resolver

Constant Summary collapse

EXIT_FAILURE_BUT_NOT_BUG =
30
EXIT_BUG =
1
EXIT_SUCCESS =
0
GenericAbort =

Abort, Bug, AbortSilent, and BugSilent are four ways of immediately bailing on command-line execution when an unrecoverable error occurs.

Note that these don’t inherit from StandardError, and so are not caught by a bare ‘rescue => e`.

  • Abort prints its message in red and exits 1;

  • Bug additionally submits the exception to the exception_reporter passed to

    `CLI::Kit::ErrorHandler.new`
    
  • AbortSilent and BugSilent do the same as above, but do not print

    messages before exiting.
    

Treat these like panic() in Go:

* Don't rescue them. Use a different Exception class if you plan to recover;
* Provide a useful message, since it will be presented in brief to the
    user, and will be useful for debugging.
* Avoid using it if it does actually make sense to recover from an error.

Additionally:

* Do not subclass these.
* Only use AbortSilent or BugSilent if you prefer to print a more
    contextualized error than Abort or Bug would present to the user.
* In general, don't attach a message to AbortSilent or BugSilent.
* Never raise GenericAbort directly.
* Think carefully about whether Abort or Bug is more appropriate. Is this
    a bug in the tool? Or is it just user error, transient network
    failure, etc.?
* One case where it's ok to rescue (cli-kit internals or tests aside):
    1. rescue Abort or Bug
    2. Print a contextualized error message
    3. Re-raise AbortSilent or BugSilent respectively.

These aren’t the only exceptions that can carry this ‘bug’ and ‘silent’ metadata, however:

If you raise an exception with ‘CLI::Kit.raise(…, bug: x, silent: y)`, those last two (optional) keyword arguments will attach the metadata to whatever exception you raise. This is interpreted later in the ErrorHandler to decide how to print output and whether to submit the exception to bugsnag.

Class.new(Exception)
VERSION =
'5.2.0'

Class Method Summary collapse

Class Method Details

.raise(exception = UNTYPED_NIL, string = UNTYPED_NIL, array = UNTYPED_NIL, cause: $ERROR_INFO, bug: nil, silent: nil, depth: 1) ⇒ Object

Mirrors the API of Kernel#raise, but with the addition of a few new optional keyword arguments. bug and silent attach metadata to the exception being raised, which is interpreted later in the ErrorHandler to decide what to print and whether to submit to bugsnag.

depth is used to trim leading elements of the backtrace. If you wrap this method in your own wrapper, you’ll want to pass ‘depth: 2`, for example. : (?(Class | String | Exception) exception, ?untyped string, ?Array? array, ?cause: Exception?, ?bug: bool?, ?silent: bool?, ?depth: Integer) -> bot



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/cli/kit.rb', line 113

def raise(
  # default arguments
  exception = UNTYPED_NIL,
  string = UNTYPED_NIL,
  array = UNTYPED_NIL,
  cause: $ERROR_INFO,
  # new arguments
  bug: nil, silent: nil, depth: 1
)
  k = Kernel #: as untyped
  if array
    k.raise(exception, string, array, cause: cause)
  elsif string
    k.raise(exception, string, Kernel.caller(depth), cause: cause)
  elsif exception.is_a?(String)
    k.raise(RuntimeError, exception, Kernel.caller(depth), cause: cause)
  else
    k.raise(exception, exception.message, Kernel.caller(depth), cause: cause)
  end
rescue Exception => e # rubocop:disable Lint/RescueException
  e.bug!(bug) unless bug.nil?
  e.silent!(silent) unless silent.nil?
  Kernel.raise(e, cause: cause)
end