class CLI::Kit::ErrorHandler

Attributes

exception[W]

maybe we can get rid of this.

Public Class Methods

new(log_file:, exception_reporter:, tool_name: nil) click to toggle source
# File lib/cli/kit/error_handler.rb, line 7
def initialize(log_file:, exception_reporter:, tool_name: nil)
  @log_file = log_file
  @exception_reporter_or_proc = exception_reporter || NullExceptionReporter
  @tool_name = tool_name
end

Public Instance Methods

call(&block) click to toggle source
# File lib/cli/kit/error_handler.rb, line 19
def call(&block)
  install!
  handle_abort(&block)
end
handle_exception(error) click to toggle source
# File lib/cli/kit/error_handler.rb, line 24
def handle_exception(error)
  if notify_with = exception_for_submission(error)
    logs = begin
      File.read(@log_file)
    rescue => e
      "(#{e.class}: #{e.message})"
    end
    exception_reporter.report(notify_with, logs)
  end
end

Private Instance Methods

exception_for_submission(error) click to toggle source
# File lib/cli/kit/error_handler.rb, line 40
def exception_for_submission(error)
  case error
  when nil         # normal, non-error termination
    nil
  when Interrupt   # ctrl-c
    nil
  when CLI::Kit::Abort, CLI::Kit::AbortSilent # Not a bug
    nil
  when SignalException
    skip = %w(SIGTERM SIGHUP SIGINT)
    skip.include?(error.message) ? nil : error
  when SystemExit # "exit N" called
    case error.status
    when CLI::Kit::EXIT_SUCCESS # submit nothing if it was `exit 0`
      nil
    when CLI::Kit::EXIT_FAILURE_BUT_NOT_BUG
      # if it was `exit 30`, translate the exit code to 1, and submit nothing.
      # 30 is used to signal normal failures that are not indicative of bugs.
      # However, users should see it presented as 1.
      exit 1
    else
      # A weird termination status happened. `error.exception "message"` will maintain backtrace
      # but allow us to set a message
      error.exception("abnormal termination status: #{error.status}")
    end
  else
    error
  end
end
exception_reporter() click to toggle source
# File lib/cli/kit/error_handler.rb, line 98
def exception_reporter
  if @exception_reporter_or_proc.respond_to?(:report)
    @exception_reporter_or_proc
  else
    @exception_reporter_or_proc.call
  end
end
format_error_message(msg) click to toggle source
# File lib/cli/kit/error_handler.rb, line 106
def format_error_message(msg)
  CLI::UI.fmt("{{red:#{msg}}}")
end
handle_abort() { || ... } click to toggle source
# File lib/cli/kit/error_handler.rb, line 74
def handle_abort
  yield
  CLI::Kit::EXIT_SUCCESS
rescue CLI::Kit::GenericAbort => e
  is_bug    = e.is_a?(CLI::Kit::Bug) || e.is_a?(CLI::Kit::BugSilent)
  is_silent = e.is_a?(CLI::Kit::AbortSilent) || e.is_a?(CLI::Kit::BugSilent)

  print_error_message(e) unless is_silent
  (@exception = e) if is_bug

  CLI::Kit::EXIT_FAILURE_BUT_NOT_BUG
rescue Interrupt
  $stderr.puts(format_error_message("Interrupt"))
  CLI::Kit::EXIT_FAILURE_BUT_NOT_BUG
rescue Errno::ENOSPC
  message = if @tool_name
    "Your disk is full - {{command:#{@tool_name}}} requires free space to operate"
  else
    "Your disk is full - free space is required to operate"
  end
  $stderr.puts(format_error_message(message))
  CLI::Kit::EXIT_FAILURE_BUT_NOT_BUG
end
install!() click to toggle source
# File lib/cli/kit/error_handler.rb, line 70
def install!
  at_exit { handle_exception(@exception || $ERROR_INFO) }
end
print_error_message(e) click to toggle source