Class: Chef::Formatters::ErrorInspectors::CompileErrorInspector
- Inherits:
-
Object
- Object
- Chef::Formatters::ErrorInspectors::CompileErrorInspector
- 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
-
#exception ⇒ Object
readonly
Returns the value of attribute exception.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Instance Method Summary collapse
- #add_explanation(error_description) ⇒ Object
- #backtrace_lines_in_cookbooks ⇒ Object
- #context ⇒ Object
- #culprit_backtrace_entry ⇒ Object
- #culprit_file ⇒ Object
- #culprit_line ⇒ Object
- #display_lower_bound ⇒ Object
- #display_upper_bound ⇒ Object
- #exception_message_modifying_frozen? ⇒ Boolean
- #file_lines ⇒ Object
- #filtered_bt ⇒ Object
- #found_error_in_cookbooks? ⇒ Boolean
-
#initialize(path, exception) ⇒ CompileErrorInspector
constructor
A new instance of CompileErrorInspector.
Constructor Details
#initialize(path, exception) ⇒ CompileErrorInspector
Returns a new instance of CompileErrorInspector.
31 32 33 34 35 36 37 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 31 def initialize(path, exception) @path, @exception = path, exception @backtrace_lines_in_cookbooks = nil @file_lines = nil @culprit_backtrace_entry = nil @culprit_line = nil end |
Instance Attribute Details
#exception ⇒ Object (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 |
#path ⇒ Object (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
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 39 def add_explanation(error_description) error_description.section(exception.class.name, exception.) if found_error_in_cookbooks? traceback = filtered_bt.map { |line| " #{line}" }.join("\n") error_description.section("Cookbook Trace: (most recent call first)", traceback) error_description.section("Relevant File Content:", context) end if msg = <<-MESSAGE Ruby objects are often frozen to prevent further modifications when they would negatively impact the process (e.g. values inside Ruby's ENV class) or to prevent polluting other objects when default values are passed by reference to many instances of an object (e.g. the empty Array as a Chef resource default, passed by reference to every instance of the resource). Chef uses Object#freeze to ensure the default values of properties inside Chef resources are not modified, so that when a new instance of a Chef resource is created, and Object#dup copies values by reference, the new resource is not receiving a default value that has been by a previous instance of that resource. Instead of modifying an object that contains a default value for all instances of a Chef resource, create a new object and assign it to the resource's parameter, e.g.: fruit_basket = resource(:fruit_basket, 'default') # BAD: modifies 'contents' object for all new fruit_basket instances fruit_basket.contents << 'apple' # GOOD: allocates new array only owned by this fruit_basket instance fruit_basket.contents %w(apple) MESSAGE error_description.section("Additional information:", msg.gsub(/^ {6}/, "")) end end |
#backtrace_lines_in_cookbooks ⇒ Object
136 137 138 139 140 141 142 143 144 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 136 def backtrace_lines_in_cookbooks @backtrace_lines_in_cookbooks ||= begin filters = Array(Chef::Config.cookbook_path).map { |p| /^#{Regexp.escape(p)}/i } r = exception.backtrace.select { |line| filters.any? { |filter| line =~ filter } } Chef::Log.trace("Filtered backtrace of compile error: #{r.join(",")}") r end end |
#context ⇒ Object
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 81 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_entry ⇒ Object
108 109 110 111 112 113 114 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 108 def culprit_backtrace_entry @culprit_backtrace_entry ||= begin bt_entry = filtered_bt.first Chef::Log.trace("Backtrace entry for compile error: '#{bt_entry}'") bt_entry end end |
#culprit_file ⇒ Object
124 125 126 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 124 def culprit_file @culprit_file ||= culprit_backtrace_entry[/^((?:.\:)?[^:]+):(\d+)/, 1] end |
#culprit_line ⇒ Object
116 117 118 119 120 121 122 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 116 def culprit_line @culprit_line ||= begin line_number = culprit_backtrace_entry[/^(?:.\:)?[^:]+:(\d+)/, 1].to_i Chef::Log.trace("Line number of compile error: '#{line_number}'") line_number end end |
#display_lower_bound ⇒ Object
92 93 94 95 96 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 92 def display_lower_bound lower = (culprit_line - 8) lower = 0 if lower < 0 lower end |
#display_upper_bound ⇒ Object
98 99 100 101 102 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 98 def display_upper_bound upper = (culprit_line + 8) upper = file_lines.size if upper > file_lines.size upper end |
#exception_message_modifying_frozen? ⇒ Boolean
146 147 148 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 146 def exception..include?("can't modify frozen") end |
#file_lines ⇒ Object
104 105 106 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 104 def file_lines @file_lines ||= IO.readlines(culprit_file) end |
#filtered_bt ⇒ Object
128 129 130 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 128 def filtered_bt backtrace_lines_in_cookbooks.count > 0 ? backtrace_lines_in_cookbooks : exception.backtrace end |
#found_error_in_cookbooks? ⇒ Boolean
132 133 134 |
# File 'lib/chef/formatters/error_inspectors/compile_error_inspector.rb', line 132 def found_error_in_cookbooks? !backtrace_lines_in_cookbooks.empty? end |