diff options
| author | tomoya ishida <tomoyapenguin@gmail.com> | 2023-11-25 19:15:58 +0900 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2023-11-25 10:16:02 +0000 |
| commit | f6b292b5ca8b397b00cc4e82d8ae7ede8b09f25f (patch) | |
| tree | 91cfcdb200a82efab856e9aed82247b3985c3c72 | |
| parent | 68a03613d8f7ec173addbfbb3989045d8f639ec5 (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.rb | 67 | ||||
| -rw-r--r-- | test/irb/test_raise_exception.rb | 7 |
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 |
