mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[ruby/irb] Use Exception#full_message to show backtrace in the correct order
[Bug #17466] https://github.com/ruby/irb/commit/1c76845cca
This commit is contained in:
parent
ed3264d37a
commit
917050220a
3 changed files with 97 additions and 42 deletions
74
lib/irb.rb
74
lib/irb.rb
|
@ -610,50 +610,44 @@ module IRB
|
|||
irb_bug = false
|
||||
end
|
||||
|
||||
if STDOUT.tty?
|
||||
attr = ATTR_TTY
|
||||
print "#{attr[1]}Traceback#{attr[]} (most recent call last):\n"
|
||||
else
|
||||
attr = ATTR_PLAIN
|
||||
end
|
||||
messages = []
|
||||
lasts = []
|
||||
levels = 0
|
||||
if exc.backtrace
|
||||
count = 0
|
||||
exc.backtrace.each do |m|
|
||||
m = @context.workspace.filter_backtrace(m) or next unless irb_bug
|
||||
count += 1
|
||||
if attr == ATTR_TTY
|
||||
m = sprintf("%9d: from %s", count, m)
|
||||
order = nil
|
||||
if '2.5.0' == RUBY_VERSION
|
||||
# Exception#full_message doesn't have keyword arguments.
|
||||
message = exc.full_message # the same of (highlight: true, order: bottom)
|
||||
order = :bottom
|
||||
elsif '2.5.1' <= RUBY_VERSION && RUBY_VERSION < '3.0.0'
|
||||
if STDOUT.tty?
|
||||
message = exc.full_message(order: :bottom)
|
||||
order = :bottom
|
||||
else
|
||||
m = "\tfrom #{m}"
|
||||
message = exc.full_message(order: :top)
|
||||
order = :top
|
||||
end
|
||||
if messages.size < @context.back_trace_limit
|
||||
messages.push(m)
|
||||
elsif lasts.size < @context.back_trace_limit
|
||||
lasts.push(m).shift
|
||||
levels += 1
|
||||
else # RUBY_VERSION < '2.5.0' || '3.0.0' <= RUBY_VERSION
|
||||
message = exc.full_message(order: :top)
|
||||
order = :top
|
||||
end
|
||||
message = convert_invalid_byte_sequence(message)
|
||||
message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
|
||||
case order
|
||||
when :top
|
||||
lines = m.split("\n")
|
||||
when :bottom
|
||||
lines = m.split("\n").reverse
|
||||
end
|
||||
end
|
||||
end
|
||||
if attr == ATTR_TTY
|
||||
unless lasts.empty?
|
||||
puts lasts.reverse
|
||||
printf "... %d levels...\n", levels if levels > 0
|
||||
end
|
||||
puts messages.reverse
|
||||
end
|
||||
converted_exc_s = convert_invalid_byte_sequence(exc.to_s.dup)
|
||||
m = converted_exc_s.split(/\n/)
|
||||
print "#{attr[1]}#{exc.class} (#{attr[4]}#{m.shift}#{attr[0, 1]})#{attr[]}\n"
|
||||
puts m.map {|s| "#{attr[1]}#{s}#{attr[]}\n"}
|
||||
if attr == ATTR_PLAIN
|
||||
puts messages
|
||||
unless lasts.empty?
|
||||
puts lasts
|
||||
printf "... %d levels...\n", levels if levels > 0
|
||||
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[0..(@context.back_trace_limit - 1)]
|
||||
lines << '... %d levels...' % omit
|
||||
end
|
||||
end
|
||||
lines = lines.reverse if order == :bottom
|
||||
lines.map{ |l| l + "\n" }.join
|
||||
}
|
||||
puts message
|
||||
end
|
||||
print "Maybe IRB bug!\n" if irb_bug
|
||||
end
|
||||
|
|
|
@ -83,6 +83,7 @@ module TestIRB
|
|||
end
|
||||
|
||||
def test_eval_input
|
||||
skip if RUBY_ENGINE == 'truffleruby'
|
||||
verbose, $VERBOSE = $VERBOSE, nil
|
||||
input = TestInputMethod.new([
|
||||
"raise 'Foo'\n",
|
||||
|
@ -95,7 +96,7 @@ module TestIRB
|
|||
irb.eval_input
|
||||
end
|
||||
assert_empty err
|
||||
assert_pattern_list([:*, /RuntimeError \(.*Foo.*\).*\n/,
|
||||
assert_pattern_list([:*, /\(irb\):1:in `<main>': Foo \(RuntimeError\)\n/,
|
||||
:*, /#<RuntimeError: Foo>\n/,
|
||||
:*, /0$/,
|
||||
:*, /0$/,
|
||||
|
@ -415,5 +416,65 @@ module TestIRB
|
|||
assert_equal("=> abc\ndef\n",
|
||||
out)
|
||||
end
|
||||
|
||||
def test_eval_input_with_exception
|
||||
skip if RUBY_ENGINE == 'truffleruby'
|
||||
verbose, $VERBOSE = $VERBOSE, nil
|
||||
input = TestInputMethod.new([
|
||||
"def hoge() fuga; end; def fuga() raise; end; hoge\n",
|
||||
])
|
||||
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
|
||||
out, err = capture_output do
|
||||
irb.eval_input
|
||||
end
|
||||
assert_empty err
|
||||
if '2.5.0' <= RUBY_VERSION && RUBY_VERSION < '3.0.0'
|
||||
expected = [
|
||||
:*, /Traceback \(most recent call last\):\n/,
|
||||
:*, /\t 2: from \(irb\):1:in `<main>'\n/,
|
||||
:*, /\t 1: from \(irb\):1:in `hoge'\n/,
|
||||
:*, /\(irb\):1:in `fuga': unhandled exception\n/,
|
||||
]
|
||||
else
|
||||
expected = [
|
||||
:*, /\(irb\):1:in `fuga': unhandled exception\n/,
|
||||
:*, /\tfrom \(irb\):1:in `hoge'\n/,
|
||||
:*, /\tfrom \(irb\):1:in `<main>'\n/,
|
||||
]
|
||||
end
|
||||
assert_pattern_list(expected, out)
|
||||
ensure
|
||||
$VERBOSE = verbose
|
||||
end
|
||||
|
||||
def test_eval_input_with_invalid_byte_sequence_exception
|
||||
skip if RUBY_ENGINE == 'truffleruby'
|
||||
verbose, $VERBOSE = $VERBOSE, nil
|
||||
input = TestInputMethod.new([
|
||||
%Q{def hoge() fuga; end; def fuga() raise "A\\xF3B"; end; hoge\n},
|
||||
])
|
||||
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
|
||||
out, err = capture_output do
|
||||
irb.eval_input
|
||||
end
|
||||
assert_empty err
|
||||
if '2.5.0' <= RUBY_VERSION && RUBY_VERSION < '3.0.0'
|
||||
expected = [
|
||||
:*, /Traceback \(most recent call last\):\n/,
|
||||
:*, /\t 2: from \(irb\):1:in `<main>'\n/,
|
||||
:*, /\t 1: from \(irb\):1:in `hoge'\n/,
|
||||
:*, /\(irb\):1:in `fuga': A\\xF3B \(RuntimeError\)\n/,
|
||||
]
|
||||
else
|
||||
expected = [
|
||||
:*, /\(irb\):1:in `fuga': A\\xF3B \(RuntimeError\)\n/,
|
||||
:*, /\tfrom \(irb\):1:in `hoge'\n/,
|
||||
:*, /\tfrom \(irb\):1:in `<main>'\n/,
|
||||
]
|
||||
end
|
||||
assert_pattern_list(expected, out)
|
||||
ensure
|
||||
$VERBOSE = verbose
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ IRB
|
|||
def test_raise_exception_with_invalid_byte_sequence
|
||||
skip if RUBY_ENGINE == 'truffleruby'
|
||||
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
|
||||
assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<~IRB, /StandardError \(A\\xF3B\)/, [])
|
||||
assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<~IRB, /A\\xF3B \(StandardError\)/, [])
|
||||
raise StandardError, "A\\xf3B"
|
||||
IRB
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue