summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomoya ishida <tomoyapenguin@gmail.com>2023-11-25 19:15:58 +0900
committergit <svn-admin@ruby-lang.org>2023-11-25 10:16:02 +0000
commitf6b292b5ca8b397b00cc4e82d8ae7ede8b09f25f (patch)
tree91cfcdb200a82efab856e9aed82247b3985c3c72
parent68a03613d8f7ec173addbfbb3989045d8f639ec5 (diff)
[ruby/irb] Fix exception(backtrace=nil) prints nothing
(https://github.com/ruby/irb/pull/782) https://github.com/ruby/irb/commit/fa9ecf9a5b
-rw-r--r--lib/irb.rb67
-rw-r--r--test/irb/test_raise_exception.rb7
2 files changed, 34 insertions, 40 deletions
diff --git a/lib/irb.rb b/lib/irb.rb
index 7547654257..8c3039482e 100644
--- a/lib/irb.rb
+++ b/lib/irb.rb
@@ -697,7 +697,7 @@ module IRB
end
def handle_exception(exc)
- if exc.backtrace && exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
+ if exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
!(SyntaxError === exc) && !(EncodingError === exc)
# The backtrace of invalid encoding hash (ex. {"\xAE": 1}) raises EncodingError without lineno.
irb_bug = true
@@ -705,44 +705,41 @@ module IRB
irb_bug = false
end
- if exc.backtrace
- order = nil
- if RUBY_VERSION < '3.0.0'
- if STDOUT.tty?
- message = exc.full_message(order: :bottom)
- order = :bottom
- else
- message = exc.full_message(order: :top)
- order = :top
- end
- else # '3.0.0' <= RUBY_VERSION
+ if RUBY_VERSION < '3.0.0'
+ if STDOUT.tty?
+ message = exc.full_message(order: :bottom)
+ order = :bottom
+ else
message = exc.full_message(order: :top)
order = :top
end
- message = convert_invalid_byte_sequence(message, exc.message.encoding)
- message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
- message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
- case order
- when :top
- lines = m.split("\n")
- when :bottom
- lines = m.split("\n").reverse
- end
- unless irb_bug
- lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact
- if lines.size > @context.back_trace_limit
- omit = lines.size - @context.back_trace_limit
- lines = lines[0..(@context.back_trace_limit - 1)]
- lines << "\t... %d levels..." % omit
- end
- end
- lines = lines.reverse if order == :bottom
- lines.map{ |l| l + "\n" }.join
- }
- # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
- message = message.gsub(/\(irb\):(?<num>\d+):in `<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in `<main>'" }
- puts message
+ else # '3.0.0' <= RUBY_VERSION
+ message = exc.full_message(order: :top)
+ order = :top
end
+ message = convert_invalid_byte_sequence(message, exc.message.encoding)
+ message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
+ message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
+ case order
+ when :top
+ lines = m.split("\n")
+ when :bottom
+ lines = m.split("\n").reverse
+ end
+ unless irb_bug
+ lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact
+ if lines.size > @context.back_trace_limit
+ omit = lines.size - @context.back_trace_limit
+ lines = lines[0..(@context.back_trace_limit - 1)]
+ lines << "\t... %d levels..." % omit
+ end
+ end
+ lines = lines.reverse if order == :bottom
+ lines.map{ |l| l + "\n" }.join
+ }
+ # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
+ message = message.gsub(/\(irb\):(?<num>\d+):in `<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in `<main>'" }
+ puts message
puts 'Maybe IRB bug!' if irb_bug
rescue Exception => handler_exc
begin
diff --git a/test/irb/test_raise_exception.rb b/test/irb/test_raise_exception.rb
index 9ca534dba1..c373dd7335 100644
--- a/test/irb/test_raise_exception.rb
+++ b/test/irb/test_raise_exception.rb
@@ -7,11 +7,8 @@ module TestIRB
class RaiseExceptionTest < TestCase
def test_raise_exception_with_nil_backtrace
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, /Exception: foo/, [])
- e = Exception.new("foo")
- puts e.inspect
- def e.backtrace; nil; end
- raise e
+ assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, /#<Exception: foo>/, [])
+ raise Exception.new("foo").tap {|e| def e.backtrace; nil; end }
IRB
end