# class Chef::Formatters::ErrorInspectors::ResourceFailureInspector

### Attributes

action[R]
exception[R]
resource[R]

### Public Class Methods

new(resource, action, exception) click to toggle source

    # File lib/chef/formatters/error_inspectors/resource_failure_inspector.rb, line 29
    def initialize(resource, action, exception)
      @resource = resource
      @action = action
      @exception = exception
    end

### Public Instance Methods

add_explanation(error_description) click to toggle source

    # File lib/chef/formatters/error_inspectors/resource_failure_inspector.rb, line 35
    def add_explanation(error_description)
      error_description.section(exception.class.name, exception.message)

      unless filtered_bt.empty?
        error_description.section("Cookbook Trace:", filtered_bt.join("\n"))
      end

      unless dynamic_resource?
        error_description.section("Resource Declaration:", recipe_snippet)
      end

      error_description.section("Compiled Resource:", "#{resource.to_text}")

      # Template errors get wrapped in an exception class that can show the relevant template code,
      # so add them to the error output.
      if exception.respond_to?(:source_listing)
        error_description.section("Template Context:", "#{exception.source_location}\n#{exception.source_listing}")
      end

      if Chef::Platform.windows?
        require 'chef/win32/security'

        if !Chef::ReservedNames::Win32::Security.has_admin_privileges?
          error_description.section("Missing Windows Admin Privileges", "chef-client doesn't have administrator privileges. This can be a possible reason for the resource failure.")
        end
      end
    end

dynamic_resource?() click to toggle source

    # File lib/chef/formatters/error_inspectors/resource_failure_inspector.rb, line 97
    def dynamic_resource?
      !resource.source_line
    end

filtered_bt() click to toggle source

    # File lib/chef/formatters/error_inspectors/resource_failure_inspector.rb, line 101
    def filtered_bt
      filters = Array(Chef::Config.cookbook_path).map {|p| /^#{Regexp.escape(p)}/ }
      exception.backtrace.select {|line| filters.any? {|filter| line =~ filter }}
    end

recipe_snippet() click to toggle source

    # File lib/chef/formatters/error_inspectors/resource_failure_inspector.rb, line 63
    def recipe_snippet
      return nil if dynamic_resource?
      @snippet ||= begin
        if file = resource.source_line[/^(([\w]:)?[^:]+):([\d]+)/,1] and line = resource.source_line[/^#{file}:([\d]+)/,1].to_i
          return nil unless ::File.exists?(file)
          lines = IO.readlines(file)

          relevant_lines = ["# In #{file}\n\n"]

          current_line = line - 1
          current_line = 0 if current_line < 0
          nesting = 0

          loop do

            # low rent parser. try to gracefully handle nested blocks in resources
            nesting += 1 if lines[current_line] =~ /[\s]+do[\s]*/
            nesting -= 1 if lines[current_line] =~ /end[\s]*$/

            relevant_lines << format_line(current_line, lines[current_line])

            break if lines[current_line + 1].nil?
            break if current_line >= (line + 50)
            break if nesting <= 0

            current_line += 1
          end
          relevant_lines << format_line(current_line + 1, lines[current_line + 1]) if lines[current_line + 1]
          relevant_lines.join("")
        end
      end
    end