lib/console/event/failure.rb in console-1.24.0 vs lib/console/event/failure.rb in console-1.25.0

- old
+ new

@@ -1,84 +1,75 @@ # frozen_string_literal: true # Released under the MIT License. -# Copyright, 2019-2022, by Samuel Williams. +# Copyright, 2019-2024, by Samuel Williams. # Copyright, 2021, by Robert Schulze. require_relative 'generic' module Console module Event + # Represents a failure event. + # + # ```ruby + # Console::Event::Failure.for(exception).emit(self) + # ``` class Failure < Generic - def self.current_working_directory + def self.default_root Dir.getwd rescue # e.g. Errno::EMFILE nil end def self.for(exception) - self.new(exception, self.current_working_directory) + self.new(exception, self.default_root) end - def initialize(exception, root = nil) + def self.log(subject, exception, **options) + Console.error(subject, **self.for(exception).to_hash, **options) + end + + def initialize(exception, root = Dir.getwd) @exception = exception @root = root end - attr :exception - attr :root - - def self.register(terminal) - terminal[:exception_title] ||= terminal.style(:red, nil, :bold) - terminal[:exception_detail] ||= terminal.style(:yellow) - terminal[:exception_backtrace] ||= terminal.style(:red) - terminal[:exception_backtrace_other] ||= terminal.style(:red, nil, :faint) - terminal[:exception_message] ||= terminal.style(:default) + def to_hash + Hash.new.tap do |hash| + hash[:type] = :failure + hash[:root] = @root if @root + extract(@exception, hash) + end end - def to_h - {exception: @exception, root: @root} + def emit(*arguments, **options) + options[:severity] ||= :error + + super end - def format(output, terminal, verbose) - format_exception(@exception, nil, output, terminal, verbose) - end + private - if Exception.method_defined?(:detailed_message) - def detailed_message(exception) - exception.detailed_message - end - else - def detailed_message(exception) - exception.message - end - end - - def format_exception(exception, prefix, output, terminal, verbose) - lines = detailed_message(exception).lines.map(&:chomp) + def extract(exception, hash) + hash[:class] = exception.class.name - output.puts " #{prefix}#{terminal[:exception_title]}#{exception.class}#{terminal.reset}: #{lines.shift}" - - lines.each do |line| - output.puts " #{terminal[:exception_detail]}#{line}#{terminal.reset}" - end - - root_pattern = /^#{@root}\// if @root - - exception.backtrace&.each_with_index do |line, index| - path, offset, message = line.split(":", 3) - style = :exception_backtrace + if exception.respond_to?(:detailed_message) + message = exception.detailed_message - # Make the path a bit more readable - if root_pattern and path.sub!(root_pattern, "").nil? - style = :exception_backtrace_other - end + # We want to remove the trailling exception class as we format it differently: + message.sub!(/\s*\(.*?\)$/, '') - output.puts " #{index == 0 ? "→" : " "} #{terminal[style]}#{path}:#{offset}#{terminal[:exception_message]} #{message}#{terminal.reset}" + hash[:message] = message + else + hash[:message] = exception.message end - if exception.cause - format_exception(exception.cause, "Caused by ", output, terminal, verbose) + hash[:backtrace] = exception.backtrace + + if cause = exception.cause + hash[:cause] = Hash.new.tap do |cause_hash| + extract(cause, cause_hash) + end end end end end end