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".freeze
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.
-
#target_host ⇒ Object
readonly
Returns the value of attribute target_host.
-
#translation ⇒ Object
readonly
Returns the value of attribute translation.
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
TODO this gets moved to trainerrormapper or simply removed since many of these issues are now handled in the RemoteTarget::ConnectionFailure.
- #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.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/chef_apply/ui/error_printer.rb', line 92 def initialize(wrapper, unwrapped = nil, target_host = nil) @exception = unwrapped || wrapper.contained_exception @target_host = wrapper.target_host || target_host @command = exception.respond_to?(:command) ? exception.command : nil @pastel = Pastel.new @content = StringIO.new @id = if exception.is_a? ChefApply::Error exception.id else DEFAULT_ERROR_NO end @translation = ChefApply::Text::ErrorTranslation.new(id) 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 |
#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 |
#translation ⇒ Object (readonly)
Returns the value of attribute translation.
28 29 30 |
# File 'lib/chef_apply/ui/error_printer.rb', line 28 def translation @translation end |
Class Method Details
.capture_multiple_failures(e) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/chef_apply/ui/error_printer.rb', line 51 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.
82 83 84 85 86 87 88 89 90 |
# File 'lib/chef_apply/ui/error_printer.rb', line 82 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
181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/chef_apply/ui/error_printer.rb', line 181 def self.error_summary(e) if e.is_a? ChefApply::Error # By convention, all of our defined messages have a short summary on the first line. ChefApply::Text.errors.send(e.id).text(*e.params).split("\n").first elsif e.is_a? String e else if e.respond_to? :message e. else ChefApply::Text.errors.UNKNOWN end end end |
.show_error(e) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/chef_apply/ui/error_printer.rb', line 38 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
70 71 72 73 74 75 76 77 78 |
# File 'lib/chef_apply/ui/error_printer.rb', line 70 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
245 246 247 248 249 |
# File 'lib/chef_apply/ui/error_printer.rb', line 245 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
251 252 253 254 255 256 257 258 259 |
# File 'lib/chef_apply/ui/error_printer.rb', line 251 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
168 169 170 171 172 173 |
# File 'lib/chef_apply/ui/error_printer.rb', line 168 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
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/chef_apply/ui/error_printer.rb', line 227 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
141 142 143 144 145 146 147 148 149 |
# File 'lib/chef_apply/ui/error_printer.rb', line 141 def format_body if exception.is_a? ChefApply::Error format_workstation_exception elsif exception.is_a? Train::Error format_train_exception else format_other_exception end end |
#format_decorated ⇒ Object
127 128 129 130 131 132 133 134 135 |
# File 'lib/chef_apply/ui/error_printer.rb', line 127 def format_decorated @content << "\n" @content << format_header @content << "\n\n" @content << format_body @content << "\n" @content << @content << "\n" end |
#format_error ⇒ Object
109 110 111 112 113 114 115 116 |
# File 'lib/chef_apply/ui/error_printer.rb', line 109 def format_error if translation.decorations format_decorated else format_undecorated end @content.string end |
#format_footer ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/chef_apply/ui/error_printer.rb', line 151 def if translation.log if translation.stack t..both(ChefApply::Config.log.location, ChefApply::Config.stack_trace_path) else t..log_only(ChefApply::Config.log.location) end else if translation.stack t..stack_only else t..neither end end end |
#format_header ⇒ Object
137 138 139 |
# File 'lib/chef_apply/ui/error_printer.rb', line 137 def format_header pastel.decorate(@id, :bold) end |
#format_other_exception ⇒ Object
212 213 214 |
# File 'lib/chef_apply/ui/error_printer.rb', line 212 def format_other_exception t.send(DEFAULT_ERROR_NO).text(exception.) end |
#format_train_exception ⇒ Object
TODO this gets moved to trainerrormapper or simply removed since
many of these issues are now handled in the RemoteTarget::ConnectionFailure
203 204 205 206 207 208 209 210 |
# File 'lib/chef_apply/ui/error_printer.rb', line 203 def format_train_exception backend, host = formatted_host if host.nil? t.CHEFTRN002.text(exception.) else t.CHEFTRN001.text(backend, host, exception.) end end |
#format_undecorated ⇒ Object
118 119 120 121 122 123 124 125 |
# File 'lib/chef_apply/ui/error_printer.rb', line 118 def format_undecorated @content << "\n" @content << format_body if @command @content << "\n" @content << @command.usage end end |
#format_workstation_exception ⇒ Object
196 197 198 199 |
# File 'lib/chef_apply/ui/error_printer.rb', line 196 def format_workstation_exception params = exception.params t.send(@id).text(*params) end |
#formatted_host ⇒ Object
216 217 218 219 220 221 222 223 |
# File 'lib/chef_apply/ui/error_printer.rb', line 216 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
175 176 177 178 179 |
# File 'lib/chef_apply/ui/error_printer.rb', line 175 def save_backtrace(output) File.open(ChefApply::Config.stack_trace_path, "ab+") do |f| f.write(output.string) end end |