Parent

Class/Module Index [+]

Quicksearch

Nanoc::CLI::ErrorHandler

Catches errors and prints nice diagnostic messages, then exits.

@api private

Constants

GEM_NAMES

A hash that contains the name of the gem for a given required file. If a `require` fails, the gem name is looked up in this hash.

Public Class Methods

disable() click to toggle source

Disables error handling. This is used by the test cases to prevent error from being handled by the CLI while tests are running.

@api private

# File lib/nanoc/cli/error_handler.rb, line 33
def self.disable
  @disabled = true
end
enable() click to toggle source

Re-enables error handling after it was disabled. This is used by the test cases to prevent error from being handled by the CLI while tests are running.

@api private

# File lib/nanoc/cli/error_handler.rb, line 42
def self.enable
  @disabled = false
end
handle_while(params={}, &block) click to toggle source

Enables error handling in the given block.

@option params [Nanoc::CLI::Command, nil] command The command that is

currently being executed, or nil if there is none

@return [void]

# File lib/nanoc/cli/error_handler.rb, line 21
def self.handle_while(params={}, &block)
  if @disabled
    yield
  else
    self.new(params).handle_while(&block)
  end
end
new(params={}) click to toggle source

@option params [Nanoc::CLI::Command, nil] command The command that is

currently being executed, or nil if there is none
# File lib/nanoc/cli/error_handler.rb, line 11
def initialize(params={})
  @command = params[:command]
end

Public Instance Methods

handle_while(&block) click to toggle source

Enables error handling in the given block. This method should not be called directly; use {Nanoc::CLI::ErrorHandler.handle_while} instead.

@return [void]

@api private

# File lib/nanoc/cli/error_handler.rb, line 52
def handle_while(&block)
  # Set exit handler
  [ 'INT', 'TERM' ].each do |signal|
    Signal.trap(signal) do
      puts
      exit!(0)
    end
  end
  begin
    Signal.trap('USR1') do
      puts "Caught USR1; dumping a stack trace"
      puts caller.map { |i| "  #{i}" }.join("\n")
    end
  rescue ArgumentError
  end

  # Run
  yield
rescue Nanoc::Errors::GenericTrivial => e
  $stderr.puts "Error: #{e.message}"
  exit(1)
rescue Interrupt => e
  exit(1)
rescue StandardError, ScriptError => e
  self.print_error(e)
  exit(1)
end
write_compact_error(error, stream) click to toggle source

Writes a compact representation of the error, suitable for a terminal, on the given stream (probably stderr).

@param [Error] error The error that should be described

@param [IO] stream The stream to write the description too

@api private

@return [void]

# File lib/nanoc/cli/error_handler.rb, line 116
def write_compact_error(error, stream)
  # Header
  stream.puts
  stream.puts "Captain! We’ve been hit!"

  # Sections
  self.write_error_message(    stream, error)
  self.write_compilation_stack(stream, error)
  self.write_stack_trace(      stream, error)

  # Issue link
  self.write_issue_link(stream)
end
write_verbose_error(error, stream) click to toggle source

Writes a verbose representation of the error on the given stream.

@param [Error] error The error that should be described

@param [IO] stream The stream to write the description too

@api private

@return [void]

# File lib/nanoc/cli/error_handler.rb, line 139
def write_verbose_error(error, stream)
  # Header
  stream.puts "Crashlog created at #{Time.now}"

  # Sections
  self.write_error_message(      stream, error, :verbose => true)
  self.write_compilation_stack(  stream, error, :verbose => true)
  self.write_stack_trace(        stream, error, :verbose => true)
  self.write_version_information(stream,        :verbose => true)
  self.write_system_information( stream,        :verbose => true)
  self.write_installed_gems(     stream,        :verbose => true)
  self.write_environment(        stream,        :verbose => true)
  self.write_gemfile_lock(       stream,        :verbose => true)
  self.write_load_paths(         stream,        :verbose => true)
end

Protected Instance Methods

compiler() click to toggle source

@return [Nanoc::Compiler] The compiler for the current site

# File lib/nanoc/cli/error_handler.rb, line 170
def compiler
  site && site.compiler
end
debug?() click to toggle source

@return [Boolean] true if debug output is enabled, false if not

@see Nanoc::CLI.debug?

# File lib/nanoc/cli/error_handler.rb, line 160
def debug?
  Nanoc::CLI.debug?
end
gems_and_versions() click to toggle source

@return [Hash<String, Array>] A hash containing the gem names as keys and gem versions as value

# File lib/nanoc/cli/error_handler.rb, line 180
def gems_and_versions
  gems = {}
  Gem::Specification.find_all.sort_by { |s| [ s.name, s.version ] }.each do |spec|
    gems[spec.name] ||= []
    gems[spec.name] << spec.version.to_s
  end
  gems
end
resolution_for(error) click to toggle source

Attempts to find a resolution for the given error, or nil if no resolution can be automatically obtained.

@param [Error] error The error to find a resolution for

@return [String] The resolution for the given error

# File lib/nanoc/cli/error_handler.rb, line 229
def resolution_for(error)
  case error
  when LoadError
    # Get gem name
    matches = error.message.match(/(no such file to load|cannot load such file) -- ([^\s]+)/)
    return nil if matches.nil?
    gem_name = GEM_NAMES[matches[2]]

    # Build message
    if gem_name
      if self.using_bundler?
        "Make sure the gem is added to Gemfile and run `bundle install`."
      else
        "Install the '#{gem_name}' gem using `gem install #{gem_name}`."
      end
    end
  when RuntimeError
    if error.message =~ /^can't modify frozen/
      "You attempted to modify immutable data. Some data, such as "            "item/layout attributes and raw item/layout content, can not "            "be modified once compilation has started. (This was "            "unintentionally possible in 3.1.x and before, but has been "            "disabled in 3.2.x in order to allow compiler optimisations.)"
    end
  end
end
site() click to toggle source

@return [Nanoc::Site] The site that is currently being processed

# File lib/nanoc/cli/error_handler.rb, line 165
def site
  @command && @command.site
end
stack() click to toggle source

@return [Array] The current compilation stack

# File lib/nanoc/cli/error_handler.rb, line 175
def stack
  (compiler && compiler.stack) || []
end
using_bundler?() click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 256
def using_bundler?
  defined?(Bundler) && Bundler::SharedHelpers.in_bundle?
end
write_compilation_stack(stream, error, params={}) click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 278
def write_compilation_stack(stream, error, params={})
  self.write_section_header(stream, 'Compilation stack', params)

  if self.stack.empty?
    stream.puts "  (empty)"
  else
    self.stack.reverse.each do |obj|
      if obj.is_a?(Nanoc::ItemRep)
        stream.puts "  - [item]   #{obj.item.identifier} (rep #{obj.name})"
      else # layout
        stream.puts "  - [layout] #{obj.identifier}"
      end
    end
  end
end
write_environment(stream, params={}) click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 335
def write_environment(stream, params={})
  self.write_section_header(stream, 'Environment', params)
  ENV.sort.each do |e|
    stream.puts "#{e.first} => #{e.last.inspect}"
  end
end
write_error_message(stream, error, params={}) click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 270
def write_error_message(stream, error, params={})
  self.write_section_header(stream, 'Message', params)

  stream.puts "#{error.class}: #{error.message}"
  resolution = self.resolution_for(error)
  stream.puts "#{resolution}" if resolution
end
write_gemfile_lock(stream, params={}) click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 342
def write_gemfile_lock(stream, params={})
  if File.exist?('Gemfile.lock')
    self.write_section_header(stream, 'Gemfile.lock', params)
    stream.puts File.read('Gemfile.lock')
  end
end
write_installed_gems(stream, params={}) click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 328
def write_installed_gems(stream, params={})
  self.write_section_header(stream, 'Installed gems', params)
  self.gems_and_versions.each do |g|
    stream.puts "  #{g.first} #{g.last.join(', ')}"
  end
end
write_load_paths(stream, params={}) click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 349
def write_load_paths(stream, params={})
  self.write_section_header(stream, 'Load paths', params)
  $LOAD_PATH.each_with_index do |i, index|
    stream.puts "  #{index}. #{i}"
  end
end
write_section_header(stream, title, params={}) click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 260
def write_section_header(stream, title, params={})
  stream.puts
  if params[:verbose]
    stream.puts '===== ' + title.upcase + ':'
  else
    stream.puts "\e[1m\e[31m" + title + ':' + "\e[0m"
  end
  stream.puts
end
write_stack_trace(stream, error, params={}) click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 294
def write_stack_trace(stream, error, params={})
  self.write_section_header(stream, 'Stack trace', params)

  count = params[:verbose] ? -1 : 10
  error.backtrace[0...count].each_with_index do |item, index|
    stream.puts "  #{index}. #{item}"
  end
  if error.backtrace.size > count
    stream.puts "  ... #{error.backtrace.size - count} more lines omitted. See full crash log for details."
  end
end
write_system_information(stream, params={}) click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 319
def write_system_information(stream, params={})
  begin
    uname = `uname -a`
    self.write_section_header(stream, 'System information', params)
    stream.puts uname
  rescue Errno::ENOENT
  end
end
write_version_information(stream, params={}) click to toggle source
# File lib/nanoc/cli/error_handler.rb, line 314
def write_version_information(stream, params={})
  self.write_section_header(stream, 'Version information', params)
  stream.puts Nanoc.version_information
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.