diff --git a/lib/telebugs.rb b/lib/telebugs.rb index d6298eb..6123798 100644 --- a/lib/telebugs.rb +++ b/lib/telebugs.rb @@ -19,6 +19,8 @@ require_relative "telebugs/middleware_stack" require_relative "telebugs/truncator" +require_relative "telebugs/middleware/gem_root_filter" + module Telebugs # The general error that this library uses when it wants to raise. Error = Class.new(StandardError) diff --git a/lib/telebugs/config.rb b/lib/telebugs/config.rb index c7515f0..7ba6ef5 100644 --- a/lib/telebugs/config.rb +++ b/lib/telebugs/config.rb @@ -35,6 +35,7 @@ def reset ) @middleware = MiddlewareStack.new + @middleware.use Middleware::GemRootFilter.new end end end diff --git a/lib/telebugs/middleware/gem_root_filter.rb b/lib/telebugs/middleware/gem_root_filter.rb new file mode 100644 index 0000000..a9e6b58 --- /dev/null +++ b/lib/telebugs/middleware/gem_root_filter.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module Telebugs + class Middleware + # GemRootFilter is a middleware that filters out the root path of the gems. + # It replaces the root path with the gem name and version. + class GemRootFilter < Telebugs::Middleware + def initialize + @gem_paths = Gem.path.map { |path| /\A#{Regexp.escape(path)}\/gems\// } + end + + def call(report) + report.data[:errors].each do |error| + process_backtrace(error[:backtrace]) + end + end + + def weight + -999 + end + + private + + def process_backtrace(backtrace) + backtrace.each do |frame| + next unless (file = frame[:file]) + + process_frame(frame, file) + end + end + + def process_frame(frame, file) + @gem_paths.each do |gem_path_regex| + next unless file&.match?(gem_path_regex) + + frame[:file] = format_file(file.sub(gem_path_regex, "")) + break + end + end + + def format_file(file) + parts = file.split("/") + + gem_info = parts[0].split("-") + gem_name = gem_info[0] + gem_version = gem_info[1] + + file_path = parts[1..].join("/") + + "#{gem_name} (#{gem_version}) #{file_path}" + end + end + end +end diff --git a/test/middleware/test_gem_root_filter.rb b/test/middleware/test_gem_root_filter.rb new file mode 100644 index 0000000..6cb84c8 --- /dev/null +++ b/test/middleware/test_gem_root_filter.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require "test_helper" + +class TestGemRootFilter < Minitest::Test + def test_gem_root_filter + begin + raise StandardError.new("test error") + rescue StandardError => e + report = Telebugs::Report.new(e) + end + + Telebugs::Middleware::GemRootFilter.new.call(report) + + assert_match( + %r{/test/middleware/test_gem_root_filter.rb}, + report.data[:errors][0][:backtrace][0][:file] + ) + assert_match( + %r{\Aminitest \(.+\..+\..+\) lib/minitest/test.rb\z}, + report.data[:errors][0][:backtrace][1][:file] + ) + end +end diff --git a/test/test_config.rb b/test/test_config.rb index 0e9df3b..62d824c 100644 --- a/test/test_config.rb +++ b/test/test_config.rb @@ -32,6 +32,11 @@ def test_middleware c.middleware.use middleware_class.new end - assert_equal 1, Telebugs.config.middleware.middlewares.size + assert_equal 2, Telebugs.config.middleware.middlewares.size + end + + def test_default_middleware_list + middleware_list = Telebugs.config.middleware.middlewares.map(&:class) + assert_includes middleware_list, Telebugs::Middleware::GemRootFilter end end