Merge pull request #16014 from apainintheneck/scrub-sorbet-runtime-from-backtrace
utils/backtrace: scrub sorbet-runtime from backtrace
This commit is contained in:
commit
073a4bb925
@ -141,7 +141,7 @@ rescue UsageError => e
|
||||
Homebrew::Help.help cmd, remaining_args: args.remaining, usage_error: e.message
|
||||
rescue SystemExit => e
|
||||
onoe "Kernel.exit" if args.debug? && !e.success?
|
||||
$stderr.puts e.backtrace if args.debug?
|
||||
$stderr.puts Utils::Backtrace.clean(e) if args.debug?
|
||||
raise
|
||||
rescue Interrupt
|
||||
$stderr.puts # seemingly a newline is typical
|
||||
@ -175,7 +175,7 @@ rescue RuntimeError, SystemCallError => e
|
||||
raise if e.message.empty?
|
||||
|
||||
onoe e
|
||||
$stderr.puts e.backtrace if args.debug?
|
||||
$stderr.puts Utils::Backtrace.clean(e) if args.debug?
|
||||
|
||||
exit 1
|
||||
rescue MethodDeprecatedError => e
|
||||
@ -184,7 +184,7 @@ rescue MethodDeprecatedError => e
|
||||
$stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/homebrew-core):"
|
||||
$stderr.puts " #{Formatter.url(e.issues_url)}"
|
||||
end
|
||||
$stderr.puts e.backtrace if args.debug?
|
||||
$stderr.puts Utils::Backtrace.clean(e) if args.debug?
|
||||
exit 1
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
onoe e
|
||||
@ -196,7 +196,7 @@ rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
$stderr.puts " #{Formatter.url(OS::ISSUES_URL)}"
|
||||
end
|
||||
end
|
||||
$stderr.puts e.backtrace
|
||||
$stderr.puts Utils::Backtrace.clean(e)
|
||||
exit 1
|
||||
else
|
||||
exit 1 if Homebrew.failed?
|
||||
|
||||
@ -62,7 +62,7 @@ module Cask
|
||||
|
||||
self
|
||||
rescue => e
|
||||
odebug e, e.backtrace
|
||||
odebug e, ::Utils::Backtrace.clean(e)
|
||||
add_error "exception while auditing #{cask}: #{e.message}"
|
||||
self
|
||||
end
|
||||
|
||||
@ -339,7 +339,7 @@ module Homebrew
|
||||
# Need to rescue before `FormulaUnavailableError` (superclass of this)
|
||||
# is handled, as searching for a formula doesn't make sense here (the
|
||||
# formula was found, but there's a problem with its implementation).
|
||||
$stderr.puts e.backtrace if Homebrew::EnvConfig.developer?
|
||||
$stderr.puts Utils::Backtrace.clean(e) if Homebrew::EnvConfig.developer?
|
||||
ofail e.message
|
||||
rescue FormulaOrCaskUnavailableError, Cask::CaskUnavailableError => e
|
||||
Homebrew.failed = true
|
||||
|
||||
@ -175,7 +175,7 @@ module Homebrew
|
||||
begin
|
||||
reporter = Reporter.new(tap)
|
||||
rescue Reporter::ReporterRevisionUnsetError => e
|
||||
onoe "#{e.message}\n#{e.backtrace&.join("\n")}" if Homebrew::EnvConfig.developer?
|
||||
onoe "#{e.message}\n#{Utils::Backtrace.clean(e)&.join("\n")}" if Homebrew::EnvConfig.developer?
|
||||
next
|
||||
end
|
||||
if reporter.updated?
|
||||
@ -629,7 +629,7 @@ class Reporter
|
||||
system HOMEBREW_BREW_FILE, "link", new_full_name, "--overwrite"
|
||||
end
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
onoe "#{e.message}\n#{e.backtrace&.join("\n")}" if Homebrew::EnvConfig.developer?
|
||||
onoe "#{e.message}\n#{Utils::Backtrace.clean(e)&.join("\n")}" if Homebrew::EnvConfig.developer?
|
||||
end
|
||||
next
|
||||
end
|
||||
|
||||
@ -105,7 +105,7 @@ module Homebrew
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
retry if retry_test?(f, args: args)
|
||||
ofail "#{f.full_name}: failed"
|
||||
$stderr.puts e, e.backtrace
|
||||
$stderr.puts e, Utils::Backtrace.clean(e)
|
||||
ensure
|
||||
ENV.replace(env)
|
||||
end
|
||||
|
||||
@ -1025,7 +1025,7 @@ on_request: installed_on_request?, options: options)
|
||||
ofail "An unexpected error occurred during the `brew link` step"
|
||||
puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}"
|
||||
puts e
|
||||
puts e.backtrace if debug?
|
||||
puts Utils::Backtrace.clean(e) if debug?
|
||||
@show_summary_heading = true
|
||||
ignore_interrupts do
|
||||
keg.unlink
|
||||
@ -1081,7 +1081,7 @@ on_request: installed_on_request?, options: options)
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
puts e
|
||||
ofail "Failed to install service files"
|
||||
odebug e, e.backtrace
|
||||
odebug e, Utils::Backtrace.clean(e)
|
||||
end
|
||||
|
||||
sig { params(keg: Keg).void }
|
||||
@ -1091,7 +1091,7 @@ on_request: installed_on_request?, options: options)
|
||||
ofail "Failed to fix install linkage"
|
||||
puts "The formula built, but you may encounter issues using it or linking other"
|
||||
puts "formulae against it."
|
||||
odebug e, e.backtrace
|
||||
odebug e, Utils::Backtrace.clean(e)
|
||||
@show_summary_heading = true
|
||||
end
|
||||
|
||||
@ -1102,7 +1102,7 @@ on_request: installed_on_request?, options: options)
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
opoo "The cleaning step did not complete successfully"
|
||||
puts "Still, the installation was successful, so we will link it into your prefix."
|
||||
odebug e, e.backtrace
|
||||
odebug e, Utils::Backtrace.clean(e)
|
||||
Homebrew.failed = true
|
||||
@show_summary_heading = true
|
||||
end
|
||||
@ -1171,7 +1171,7 @@ on_request: installed_on_request?, options: options)
|
||||
opoo "The post-install step did not complete successfully"
|
||||
puts "You can try again using:"
|
||||
puts " brew postinstall #{formula.full_name}"
|
||||
odebug e, e.backtrace, always_display: Homebrew::EnvConfig.developer?
|
||||
odebug e, Utils::Backtrace.clean(e), always_display: Homebrew::EnvConfig.developer?
|
||||
Homebrew.failed = true
|
||||
@show_summary_heading = true
|
||||
end
|
||||
|
||||
@ -57,7 +57,7 @@ class FormulaVersions
|
||||
rescue *IGNORED_EXCEPTIONS => e
|
||||
# We rescue these so that we can skip bad versions and
|
||||
# continue walking the history
|
||||
odebug "#{e} in #{name} at revision #{revision}", e.backtrace
|
||||
odebug "#{e} in #{name} at revision #{revision}", Utils::Backtrace.clean(e)
|
||||
rescue FormulaUnavailableError
|
||||
nil
|
||||
ensure
|
||||
|
||||
@ -391,7 +391,7 @@ module Homebrew
|
||||
name += " (cask)" if ambiguous_casks.include?(formula_or_cask)
|
||||
|
||||
onoe "#{Tty.blue}#{name}#{Tty.reset}: #{e}"
|
||||
$stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error)
|
||||
$stderr.puts Utils::Backtrace.clean(e) if debug && !e.is_a?(Livecheck::Error)
|
||||
print_resources_info(resource_version_info, verbose: verbose) if check_for_resources
|
||||
nil
|
||||
end
|
||||
@ -1016,7 +1016,7 @@ module Homebrew
|
||||
status_hash(resource, "error", [e.to_s], verbose: verbose)
|
||||
elsif !quiet
|
||||
onoe "#{Tty.blue}#{resource.name}#{Tty.reset}: #{e}"
|
||||
$stderr.puts e.backtrace if debug && !e.is_a?(Livecheck::Error)
|
||||
$stderr.puts Utils::Backtrace.clean(e) if debug && !e.is_a?(Livecheck::Error)
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
@ -228,7 +228,7 @@ class Migrator
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
onoe "The migration did not complete successfully."
|
||||
puts e
|
||||
puts e.backtrace if debug?
|
||||
puts Utils::Backtrace.clean(e) if debug?
|
||||
puts "Backing up..."
|
||||
ignore_interrupts { backup_oldname }
|
||||
ensure
|
||||
@ -358,7 +358,7 @@ class Migrator
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
onoe "An unexpected error occurred during linking"
|
||||
puts e
|
||||
puts e.backtrace if debug?
|
||||
puts Utils::Backtrace.clean(e) if debug?
|
||||
ignore_interrupts { new_keg.unlink(verbose: verbose?) }
|
||||
raise
|
||||
end
|
||||
|
||||
90
Library/Homebrew/test/utils/backtrace_spec.rb
Normal file
90
Library/Homebrew/test/utils/backtrace_spec.rb
Normal file
@ -0,0 +1,90 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/backtrace"
|
||||
|
||||
describe Utils::Backtrace do
|
||||
let(:backtrace_no_sorbet_paths) do
|
||||
[
|
||||
"/Library/Homebrew/downloadable.rb:75:in",
|
||||
"/Library/Homebrew/downloadable.rb:50:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:236:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:201:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:178:in",
|
||||
"/Library/Homebrew/simulate_system.rb:29:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:166:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:163:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:163:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:94:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:94:in",
|
||||
"/Library/Homebrew/brew.rb:94:in",
|
||||
]
|
||||
end
|
||||
|
||||
let(:backtrace_with_sorbet_paths) do
|
||||
[
|
||||
"/Library/Homebrew/downloadable.rb:75:in",
|
||||
"/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10461/lib/call_validation.rb:157:in",
|
||||
"/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10461/lib/call_validation.rb:157:in",
|
||||
"/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10461/lib/_methods.rb:270:in",
|
||||
"/Library/Homebrew/downloadable.rb:50:in",
|
||||
"/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10461/lib/call_validation.rb:157:in",
|
||||
"/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10461/lib/call_validation.rb:157:in",
|
||||
"/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10461/lib/_methods.rb:270:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:236:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:201:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:178:in",
|
||||
"/Library/Homebrew/simulate_system.rb:29:in",
|
||||
"/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10461/lib/call_validation.rb:157:in",
|
||||
"/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10461/lib/call_validation.rb:157:in",
|
||||
"/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime-0.5.10461/lib/_methods.rb:270:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:166:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:163:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:163:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:94:in",
|
||||
"/Library/Homebrew/cmd/fetch.rb:94:in",
|
||||
"/Library/Homebrew/brew.rb:94:in",
|
||||
]
|
||||
end
|
||||
|
||||
let(:backtrace_with_sorbet_error) do
|
||||
backtrace_with_sorbet_paths.drop(1)
|
||||
end
|
||||
|
||||
def exception_with(backtrace:)
|
||||
exception = StandardError.new
|
||||
exception.set_backtrace(backtrace) if backtrace
|
||||
exception
|
||||
end
|
||||
|
||||
before do
|
||||
allow(described_class).to receive(:sorbet_runtime_path)
|
||||
.and_return("/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/sorbet-runtime")
|
||||
allow(Context).to receive(:current).and_return(Context::ContextStruct.new(verbose: false))
|
||||
end
|
||||
|
||||
it "handles nil backtrace" do
|
||||
exception = exception_with backtrace: nil
|
||||
expect(described_class.clean(exception)).to be_nil
|
||||
end
|
||||
|
||||
it "handles empty array backtrace" do
|
||||
exception = exception_with backtrace: []
|
||||
expect(described_class.clean(exception)).to eq []
|
||||
end
|
||||
|
||||
it "removes sorbet paths when top error is not from sorbet" do
|
||||
exception = exception_with backtrace: backtrace_with_sorbet_paths
|
||||
expect(described_class.clean(exception)).to eq backtrace_no_sorbet_paths
|
||||
end
|
||||
|
||||
it "includes sorbet paths when top error is not from sorbet and verbose is set" do
|
||||
allow(Context).to receive(:current).and_return(Context::ContextStruct.new(verbose: true))
|
||||
exception = exception_with backtrace: backtrace_with_sorbet_paths
|
||||
expect(described_class.clean(exception)).to eq backtrace_with_sorbet_paths
|
||||
end
|
||||
|
||||
it "doesn't change backtrace when error is from sorbet" do
|
||||
exception = exception_with backtrace: backtrace_with_sorbet_error
|
||||
expect(described_class.clean(exception)).to eq backtrace_with_sorbet_error
|
||||
end
|
||||
end
|
||||
@ -4,6 +4,7 @@
|
||||
require "time"
|
||||
|
||||
require "utils/analytics"
|
||||
require "utils/backtrace"
|
||||
require "utils/curl"
|
||||
require "utils/fork"
|
||||
require "utils/formatter"
|
||||
|
||||
36
Library/Homebrew/utils/backtrace.rb
Normal file
36
Library/Homebrew/utils/backtrace.rb
Normal file
@ -0,0 +1,36 @@
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Utils
|
||||
module Backtrace
|
||||
# Cleans `sorbet-runtime` gem paths from the backtrace unless...
|
||||
# 1. `verbose` is set
|
||||
# 2. first backtrace line starts with `sorbet-runtime`
|
||||
# - This implies that the error is related to Sorbet.
|
||||
sig { params(error: Exception).returns(T.nilable(T::Array[String])) }
|
||||
def self.clean(error)
|
||||
backtrace = error.backtrace
|
||||
|
||||
return backtrace if Context.current.verbose?
|
||||
return backtrace if backtrace.blank?
|
||||
return backtrace if backtrace.fetch(0).start_with?(sorbet_runtime_path)
|
||||
|
||||
old_backtrace_length = backtrace.length
|
||||
backtrace.reject { |line| line.start_with?(sorbet_runtime_path) }
|
||||
.tap { |new_backtrace| print_backtrace_message if old_backtrace_length > new_backtrace.length }
|
||||
end
|
||||
|
||||
def self.sorbet_runtime_path
|
||||
@sorbet_runtime_path ||= "#{Gem.paths.home}/gems/sorbet-runtime"
|
||||
end
|
||||
|
||||
def self.print_backtrace_message
|
||||
return if @print_backtrace_message
|
||||
|
||||
opoo "Removed Sorbet lines from backtrace!"
|
||||
puts "Rerun with --verbose to see the original backtrace" unless Homebrew::EnvConfig.no_env_hints?
|
||||
|
||||
@print_backtrace_message = true
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -38,7 +38,7 @@ module Repology
|
||||
data = JSON.parse(output)
|
||||
{ name => data }
|
||||
rescue => e
|
||||
error_output = [errors, "#{e.class}: #{e}", e.backtrace].compact
|
||||
error_output = [errors, "#{e.class}: #{e}", Utils::Backtrace.clean(e)].compact
|
||||
if Homebrew::EnvConfig.developer?
|
||||
$stderr.puts(*error_output)
|
||||
else
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user