From aafc615b4aff8b05efa14d30f0eb7c6adc5fde85 Mon Sep 17 00:00:00 2001 From: Daniel Niknam Date: Sun, 8 Aug 2021 16:23:31 +1000 Subject: [PATCH] [rubygems/rubygems] Enhance error handling when loading the rubygems/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 https://github.com/rubygems/rubygems/commit/0a97e12fe1 --- lib/rubygems.rb | 3 +++ test/rubygems/test_rubygems.rb | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 test/rubygems/test_rubygems.rb diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 17881e2e0e966e..e750277dd3c2f9 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -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 diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb new file mode 100644 index 00000000000000..fc2fb32f5a207a --- /dev/null +++ b/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