Class: Chef::Formatters::ErrorInspectors::CompileErrorInspector

Inherits:
Object
  • Object
show all
Defined in:
lib/chef/formatters/error_inspectors/compile_error_inspector.rb

Overview

CompileErrorInspector

Wraps exceptions that occur during the compile phase of a Chef run and tries to find the code responsible for the error.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, exception) ⇒ CompileErrorInspector

Returns a new instance of CompileErrorInspector.


31
32
33
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 31

def initialize(path, exception)
  @path, @exception = path, exception
end

Instance Attribute Details

#exceptionObject (readonly)

Returns the value of attribute exception


29
30
31
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 29

def exception
  @exception
end

#pathObject (readonly)

Returns the value of attribute path


28
29
30
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 28

def path
  @path
end

Instance Method Details

#add_explanation(error_description) ⇒ Object


35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 35

def add_explanation(error_description)
  case exception
  when Chef::Exceptions::RecipeNotFound
    error_description.section(exception.class.name, exception.message)
  else
    error_description.section(exception.class.name, exception.message)

    traceback = filtered_bt.map {|line| "  #{line}"}.join("\n")
    error_description.section("Cookbook Trace:", traceback)
    error_description.section("Relevant File Content:", context)
  end
end

#contextObject


48
49
50
51
52
53
54
55
56
57
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 48

def context
  context_lines = []
  context_lines << "#{culprit_file}:\n\n"
  Range.new(display_lower_bound, display_upper_bound).each do |i|
    line_nr = (i + 1).to_s.rjust(3)
    indicator = (i + 1) == culprit_line ? ">> " : ":  "
    context_lines << "#{line_nr}#{indicator}#{file_lines[i]}"
  end
  context_lines.join("")
end

#culprit_backtrace_entryObject


75
76
77
78
79
80
81
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 75

def culprit_backtrace_entry
  @culprit_backtrace_entry ||= begin
     bt_entry = filtered_bt.first
     Chef::Log.debug("backtrace entry for compile error: '#{bt_entry}'")
     bt_entry
  end
end

#culprit_fileObject


91
92
93
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 91

def culprit_file
  @culprit_file ||= culprit_backtrace_entry[/^((?:.\:)?[^:]+):([\d]+)/,1]
end

#culprit_lineObject


83
84
85
86
87
88
89
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 83

def culprit_line
  @culprit_line ||= begin
    line_number = culprit_backtrace_entry[/^(?:.\:)?[^:]+:([\d]+)/,1].to_i
    Chef::Log.debug("Line number of compile error: '#{line_number}'")
    line_number
  end
end

#display_lower_boundObject


59
60
61
62
63
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 59

def display_lower_bound
  lower = (culprit_line - 8)
  lower = 0 if lower < 0
  lower
end

#display_upper_boundObject


65
66
67
68
69
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 65

def display_upper_bound
  upper = (culprit_line + 8)
  upper = file_lines.size if upper > file_lines.size
  upper
end

#file_linesObject


71
72
73
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 71

def file_lines
  @file_lines ||= IO.readlines(culprit_file)
end

#filtered_btObject


95
96
97
98
99
100
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 95

def filtered_bt
  filters = Array(Chef::Config.cookbook_path).map {|p| /^#{Regexp.escape(p)}/ }
  r = exception.backtrace.select {|line| filters.any? {|filter| line =~ filter }}
  Chef::Log.debug("filtered backtrace of compile error: #{r.join(",")}")
  return r.count > 0 ? r : exception.backtrace
end