Index: test/testException.rb =================================================================== --- test/testException.rb (revision 2577) +++ test/testException.rb (working copy) @@ -74,4 +74,28 @@ test_no_exception { e = StandardError.new e.set_backtrace(nil) -} \ No newline at end of file +} + +begin + raise 'Something bad' +rescue + begin + test_ok(true) + rescue + test_ok(false) + end + test_ok($!, 'Global exception ($!) should not be nil') + test_ok($!.to_s.eql? 'Something bad', "Global exceptions should be 'Something bad', but is '#{$!}'") +end + +begin + raise 'Something bad' +rescue + begin + raise 'Something else bad' + rescue + test_ok(true) + end + test_ok($!, 'Global exception ($!) should not be nil') + test_ok($!.to_s.eql? 'Something bad', "Global exceptions should be 'Something bad', but is '#{$!}'") +end Index: src/org/jruby/evaluator/EvaluationState.java =================================================================== --- src/org/jruby/evaluator/EvaluationState.java (revision 2577) +++ src/org/jruby/evaluator/EvaluationState.java (working copy) @@ -1333,6 +1333,7 @@ case NodeTypes.RESCUENODE: { RescueNode iVisited = (RescueNode)node; RescuedBlock : while (true) { + IRubyObject globalExceptionState = runtime.getGlobalVariables().get("$!"); try { // Execute rescue block IRubyObject result = evalInternal(context, iVisited.getBodyNode(), self); @@ -1352,7 +1353,7 @@ // falsely set $! to nil and this sets it back to something valid. This should // get fixed at the same time we address bug #1296484. runtime.getGlobalVariables().set("$!", raisedException); - + RescueBodyNode rescueNode = iVisited.getRescueNode(); while (rescueNode != null) { @@ -1388,7 +1389,7 @@ throw raiseJump; } finally { // clear exception when handled or retried - runtime.getGlobalVariables().set("$!", runtime.getNil()); + runtime.getGlobalVariables().set("$!", globalExceptionState); } } }