Class: ChefApply::UI::ErrorPrinter
- Inherits:
-
Object
- Object
- ChefApply::UI::ErrorPrinter
- Defined in:
- lib/chef_apply/ui/error_printer.rb
Constant Summary collapse
- DEFAULT_ERROR_NO =
"CHEFINT001"
Instance Attribute Summary collapse
-
#exception ⇒ Object
readonly
Returns the value of attribute exception.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#pastel ⇒ Object
readonly
Returns the value of attribute pastel.
-
#show_log ⇒ Object
readonly
Returns the value of attribute show_log.
-
#show_stack ⇒ Object
readonly
Returns the value of attribute show_stack.
-
#target_host ⇒ Object
readonly
Returns the value of attribute target_host.
Class Method Summary collapse
- .capture_multiple_failures(e) ⇒ Object
-
.dump_unexpected_error(e) ⇒ Object
Use this to dump an an exception to output.
- .error_summary(e) ⇒ Object
- .show_error(e) ⇒ Object
- .write_backtrace(e, args) ⇒ Object
Instance Method Summary collapse
- #_format_single(out, exception, backtrace = nil) ⇒ Object
- #_unique_trace(backtrace1, backtrace2) ⇒ Object
- #add_backtrace_header(out, args) ⇒ Object
-
#add_formatted_backtrace(out) ⇒ Object
mostly copied from gist.github.com/stanio/13d74294ca1868fed7fb.
- #format_body ⇒ Object
- #format_decorated ⇒ Object
- #format_error ⇒ Object
- #format_footer ⇒ Object
- #format_header ⇒ Object
- #format_other_exception ⇒ Object
- #format_train_exception ⇒ Object
- #format_undecorated ⇒ Object
- #format_workstation_exception ⇒ Object
- #formatted_host ⇒ Object
-
#initialize(wrapper, unwrapped = nil, target_host = nil) ⇒ ErrorPrinter
constructor
A new instance of ErrorPrinter.
- #save_backtrace(output) ⇒ Object
-
#t ⇒ Object
TODO define ‘t’ as a method is a temporary workaround to ensure that text key lookups are testable.
Constructor Details
#initialize(wrapper, unwrapped = nil, target_host = nil) ⇒ ErrorPrinter
Returns a new instance of ErrorPrinter.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/chef_apply/ui/error_printer.rb', line 91 def initialize(wrapper, unwrapped = nil, target_host = nil) @exception = unwrapped || wrapper.contained_exception @target_host = wrapper.target_host || target_host @pastel = Pastel.new @show_log = exception.respond_to?(:show_log) ? exception.show_log : true @show_stack = exception.respond_to?(:show_stack) ? exception.show_stack : true @content = StringIO.new @command = exception.respond_to?(:command) ? exception.command : nil @id = DEFAULT_ERROR_NO if exception.respond_to?(:id) && exception.id =~ /CHEF.*/ @id = exception.id end if exception.respond_to?(:decorate) @decorate = exception.decorate else @decorate = true end rescue => e ErrorPrinter.dump_unexpected_error(e) exit! 128 end |
Instance Attribute Details
#exception ⇒ Object (readonly)
Returns the value of attribute exception.
28 29 30 |
# File 'lib/chef_apply/ui/error_printer.rb', line 28 def exception @exception end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
28 29 30 |
# File 'lib/chef_apply/ui/error_printer.rb', line 28 def id @id end |
#pastel ⇒ Object (readonly)
Returns the value of attribute pastel.
28 29 30 |
# File 'lib/chef_apply/ui/error_printer.rb', line 28 def pastel @pastel end |
#show_log ⇒ Object (readonly)
Returns the value of attribute show_log.
28 29 30 |
# File 'lib/chef_apply/ui/error_printer.rb', line 28 def show_log @show_log end |
#show_stack ⇒ Object (readonly)
Returns the value of attribute show_stack.
28 29 30 |
# File 'lib/chef_apply/ui/error_printer.rb', line 28 def show_stack @show_stack end |
#target_host ⇒ Object (readonly)
Returns the value of attribute target_host.
28 29 30 |
# File 'lib/chef_apply/ui/error_printer.rb', line 28 def target_host @target_host end |
Class Method Details
.capture_multiple_failures(e) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/chef_apply/ui/error_printer.rb', line 50 def self.capture_multiple_failures(e) out_file = ChefApply::Config.error_output_path e.params << out_file # Tell the operator where to find this info File.open(out_file, "w") do |out| e.jobs.each do |j| wrapped = ChefApply::Errors::StandardErrorResolver.wrap_exception(j.exception, j.target_host) ep = ErrorPrinter.new(wrapped) msg = ep.format_body().tr("\n", " ").gsub(/ {2,}/, " ").chomp.strip out.write("Host: #{j.target_host.hostname} ") if ep.exception.respond_to? :id out.write("Error: #{ep.exception.id}: ") else out.write(": ") end out.write("#{msg}\n") end end end |
.dump_unexpected_error(e) ⇒ Object
Use this to dump an an exception to output. useful if an error occurs in the error handling itself.
81 82 83 84 85 86 87 88 89 |
# File 'lib/chef_apply/ui/error_printer.rb', line 81 def self.dump_unexpected_error(e) Terminal.output "INTERNAL ERROR" Terminal.output "-=" * 30 Terminal.output "Message:" Terminal.output e. if e.respond_to?(:message) Terminal.output "Backtrace:" Terminal.output e.backtrace if e.respond_to?(:backtrace) Terminal.output "=-" * 30 end |
.error_summary(e) ⇒ Object
185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/chef_apply/ui/error_printer.rb', line 185 def self.error_summary(e) if e.kind_of? ChefApply::Error # By convention, all of our defined messages have a short summary on the first line. ChefApply::Text.errors.send(e.id, *e.params).split("\n").first elsif e.kind_of? String e else if e.respond_to? :message e. else ChefApply::Text.errors.UNKNOWN end end end |
.show_error(e) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/chef_apply/ui/error_printer.rb', line 37 def self.show_error(e) # Name is misleading - it's unwrapping but also doing further # error resolution for common errors: unwrapped = ChefApply::Errors::StandardErrorResolver.unwrap_exception(e) if unwrapped.class == ChefApply::MultiJobFailure capture_multiple_failures(unwrapped) end formatter = ErrorPrinter.new(e, unwrapped) Terminal.output(formatter.format_error) rescue => e dump_unexpected_error(e) end |
.write_backtrace(e, args) ⇒ Object
69 70 71 72 73 74 75 76 77 |
# File 'lib/chef_apply/ui/error_printer.rb', line 69 def self.write_backtrace(e, args) formatter = ErrorPrinter.new(e) out = StringIO.new formatter.add_backtrace_header(out, args) formatter.add_formatted_backtrace(out) formatter.save_backtrace(out) rescue => ex dump_unexpected_error(ex) end |
Instance Method Details
#_format_single(out, exception, backtrace = nil) ⇒ Object
246 247 248 249 250 |
# File 'lib/chef_apply/ui/error_printer.rb', line 246 def _format_single(out, exception, backtrace = nil) out.puts "#{exception.class}: #{exception.}" backtrace ||= exception.backtrace.to_a backtrace.each { |trace| out.puts "\t#{trace}" } end |
#_unique_trace(backtrace1, backtrace2) ⇒ Object
252 253 254 255 256 257 258 259 |
# File 'lib/chef_apply/ui/error_printer.rb', line 252 def _unique_trace(backtrace1, backtrace2) i = 1 while i <= backtrace1.size && i <= backtrace2.size break if backtrace1[-i] != backtrace2[-i] i += 1 end backtrace1[0..-i] end |
#add_backtrace_header(out, args) ⇒ Object
172 173 174 175 176 177 |
# File 'lib/chef_apply/ui/error_printer.rb', line 172 def add_backtrace_header(out, args) out.write("\n#{"-" * 80}\n") out.print("#{Time.now}: Error encountered while running the following:\n") out.print(" #{args.join(' ')}\n") out.print("Backtrace:\n") end |
#add_formatted_backtrace(out) ⇒ Object
mostly copied from gist.github.com/stanio/13d74294ca1868fed7fb
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/chef_apply/ui/error_printer.rb', line 228 def add_formatted_backtrace(out) _format_single(out, exception) current_backtrace = exception.backtrace cause = exception.cause until cause.nil? cause_trace = _unique_trace(cause.backtrace.to_a, current_backtrace) out.print "Caused by: " _format_single(out, cause, cause_trace) backtrace_length = cause.backtrace.length if backtrace_length > cause_trace.length out.print "\t... #{backtrace_length - cause_trace.length} more" end out.print "\n" current_backtrace = cause.backtrace cause = cause.cause end end |
#format_body ⇒ Object
145 146 147 148 149 150 151 152 153 |
# File 'lib/chef_apply/ui/error_printer.rb', line 145 def format_body if exception.kind_of? ChefApply::Error format_workstation_exception elsif exception.kind_of? Train::Error format_train_exception else format_other_exception end end |
#format_decorated ⇒ Object
131 132 133 134 135 136 137 138 139 |
# File 'lib/chef_apply/ui/error_printer.rb', line 131 def format_decorated @content << "\n" @content << format_header() @content << "\n\n" @content << format_body() @content << "\n" @content << () @content << "\n" end |
#format_error ⇒ Object
113 114 115 116 117 118 119 120 |
# File 'lib/chef_apply/ui/error_printer.rb', line 113 def format_error if @decorate format_decorated else format_undecorated end @content.string end |
#format_footer ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/chef_apply/ui/error_printer.rb', line 155 def if show_log if show_stack t..both(ChefApply::Config.log.location, ChefApply::Config.stack_trace_path) else t..log_only(ChefApply::Config.log.location) end else if show_stack t..stack_only else t..neither end end end |
#format_header ⇒ Object
141 142 143 |
# File 'lib/chef_apply/ui/error_printer.rb', line 141 def format_header pastel.decorate(@id, :bold) end |
#format_other_exception ⇒ Object
214 215 216 |
# File 'lib/chef_apply/ui/error_printer.rb', line 214 def format_other_exception t.send(DEFAULT_ERROR_NO, exception.) end |
#format_train_exception ⇒ Object
205 206 207 208 209 210 211 212 |
# File 'lib/chef_apply/ui/error_printer.rb', line 205 def format_train_exception backend, host = formatted_host() if host.nil? t.CHEFTRN002(exception.) else t.CHEFTRN001(backend, host, exception.) end end |
#format_undecorated ⇒ Object
122 123 124 125 126 127 128 129 |
# File 'lib/chef_apply/ui/error_printer.rb', line 122 def format_undecorated @content << "\n" @content << format_body() if @command @content << "\n" @content << @command.usage end end |
#format_workstation_exception ⇒ Object
200 201 202 203 |
# File 'lib/chef_apply/ui/error_printer.rb', line 200 def format_workstation_exception params = exception.params t.send(@id, *params) end |
#formatted_host ⇒ Object
218 219 220 221 222 223 224 |
# File 'lib/chef_apply/ui/error_printer.rb', line 218 def formatted_host return nil if target_host.nil? cfg = target_host.config port = cfg[:port].nil? ? "" : ":#{cfg[:port]}" user = cfg[:user].nil? ? "" : "#{cfg[:user]}@" "#{user}#{target_host.hostname}#{port}" end |
#save_backtrace(output) ⇒ Object
179 180 181 182 183 |
# File 'lib/chef_apply/ui/error_printer.rb', line 179 def save_backtrace(output) File.open(ChefApply::Config.stack_trace_path, "ab+") do |f| f.write(output.string) end end |