Skip to content

Commit

Permalink
[rubygems/rubygems] Enhance error handling when loading the rubygems/…
Browse files Browse the repository at this point in the history
…defaults/operating_system file

When loading `rubygems/defaults/operating_system`
- we want to keep it silent if the raised exception is a LoadError
- we want to print a message in other cases and ask users to report the issue to their OS support.

Ruby 3 comes with special error handling for loading `rubygems` and it will show a warning when LoadError exception raised for requiring 'rubygem'.
Because of that, we decided to leave the LoadError scenario as it is.
Reference: https://github.com/ruby/ruby/blob/d1998d8767affe58be0bd09ec536dae9198a7fbd/gem_prelude.rb#L1-L5

rubygems/rubygems@0a97e12fe1
  • Loading branch information
daniel-niknam authored and hsbt committed Aug 31, 2021
1 parent 9fa5c4c commit aafc615
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/rubygems.rb
Expand Up @@ -1331,6 +1331,9 @@ def default_gem_load_paths

require 'rubygems/defaults/operating_system'
rescue LoadError
# Ignored
rescue Exception => e
raise e.class, "#{e.message}\nThis is not expected so please report this issue to your OS support and ask for help."
end

begin
Expand Down
38 changes: 38 additions & 0 deletions test/rubygems/test_rubygems.rb
@@ -0,0 +1,38 @@
require_relative 'helper'

class GemTest < Gem::TestCase
def test_rubygems_normal_behaviour
_ = Gem::Util.popen(*ruby_with_rubygems_in_load_path, '-e', "'require \"rubygems\"'", {:err => [:child, :out]}).strip
assert $?.success?
end

def test_operating_system_other_exceptions
path = util_install_operating_system_rb <<-RUBY
intentional synt'ax error
RUBY

output = Gem::Util.popen(*ruby_with_rubygems_and_fake_operating_system_in_load_path(path), '-e', "'require \"rubygems\"'", {:err => [:child, :out]}).strip
assert !$?.success?
assert_includes output, "This is not expected so please report this issue to your OS support and ask for help"
end

private

def util_install_operating_system_rb(content)
dir_lib = Dir.mktmpdir("test_operating_system_lib", @tempdir)
dir_lib_arg = File.join dir_lib

dir_lib_rubygems_defaults_arg = File.join dir_lib_arg, "lib", "rubygems", "defaults"
FileUtils.mkdir_p dir_lib_rubygems_defaults_arg

operating_system_rb = File.join dir_lib_rubygems_defaults_arg, "operating_system.rb"

File.open(operating_system_rb, 'w') {|f| f.write content }

File.join dir_lib_arg, "lib"
end

def ruby_with_rubygems_and_fake_operating_system_in_load_path(operating_system_path)
[Gem.ruby, "-I", operating_system_path, "-I" , $LOAD_PATH.find{|p| p == File.dirname($LOADED_FEATURES.find{|f| f.end_with?("/rubygems.rb") }) }]
end
end

0 comments on commit aafc615

Please sign in to comment.