From a548792aa0beef4330a3d47eb75dd2fe741013bc Mon Sep 17 00:00:00 2001
From: Andrew Kreiling <agkr@pobox.com>
Date: Sun, 3 Mar 2013 07:50:59 -0600
Subject: Don't blindly call blame_file! on exceptions in
 ActiveSupport::Dependencies::Loadable

It is possible under some environments to receive an Exception that is
not extended with Blamable (e.g. JRuby).
ActiveSupport::Dependencies::Loadable#load_dependency blindly call
blame_file! on the exception which throws it's own NoMethodError
exception and hides the original Exception.

This commit fixes #9521
---
 activesupport/CHANGELOG.md                                        | 5 +++++
 activesupport/lib/active_support/dependencies.rb                  | 2 +-
 .../test/dependencies/raises_exception_without_blame_file.rb      | 5 +++++
 activesupport/test/dependencies_test.rb                           | 8 ++++++++
 4 files changed, 19 insertions(+), 1 deletion(-)
 create mode 100644 activesupport/test/dependencies/raises_exception_without_blame_file.rb

(limited to 'activesupport')

diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 5a1c14683e..0f9399f4d6 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,8 @@
+*   Fix `ActiveSupport::Dependencies::Loadable#load_dependency` calling
+    `#blame_file!` on Exceptions that do not have the Blamable mixin
+
+    *Andrew Kreiling*
+
 *   Override `Time.at` to support the passing of Time-like values when called with a single argument.
 
     *Andrew White*
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index fff4c776a9..d38e4b0732 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -213,7 +213,7 @@ module ActiveSupport #:nodoc:
           yield
         end
       rescue Exception => exception  # errors from loading file
-        exception.blame_file! file
+        exception.blame_file! file if exception.respond_to? :blame_file!
         raise
       end
 
diff --git a/activesupport/test/dependencies/raises_exception_without_blame_file.rb b/activesupport/test/dependencies/raises_exception_without_blame_file.rb
new file mode 100644
index 0000000000..4b2da6ff30
--- /dev/null
+++ b/activesupport/test/dependencies/raises_exception_without_blame_file.rb
@@ -0,0 +1,5 @@
+exception = Exception.new('I am not blamable!')
+class << exception
+  undef_method(:blame_file!)
+end
+raise exception
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index 4b1426bb2e..68b6cc6e8c 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -76,6 +76,14 @@ class DependenciesTest < ActiveSupport::TestCase
     end
   end
 
+  def test_dependency_which_raises_doesnt_blindly_call_blame_file!
+    with_loading do
+      filename = 'dependencies/raises_exception_without_blame_file'
+
+      assert_raises(Exception) { require_dependency filename }
+    end
+  end
+
   def test_warnings_should_be_enabled_on_first_load
     with_loading 'dependencies' do
       old_warnings, ActiveSupport::Dependencies.warnings_on_first_load = ActiveSupport::Dependencies.warnings_on_first_load, true
-- 
cgit v1.2.3