HBASE-26741 Incorrect exception handling in shell (#4101)
Override eval_input in HIRB to modify exception handling logic. Signed-off-by: Josh Elser <elserj@apache.org>
This commit is contained in:
parent
6c3c53a81c
commit
85fadfde26
29
LICENSE.txt
29
LICENSE.txt
|
@ -252,7 +252,7 @@ under the terms of the MIT license.
|
|||
THE SOFTWARE.
|
||||
|
||||
----
|
||||
This project incorporates portions of the 'Protocol Buffers' project avaialble
|
||||
This project incorporates portions of the 'Protocol Buffers' project available
|
||||
under a '3-clause BSD' license.
|
||||
|
||||
Copyright 2008, Google Inc.
|
||||
|
@ -612,3 +612,30 @@ available under the Creative Commons By Attribution 3.0 License.
|
|||
this trademark restriction does not form part of this License.
|
||||
|
||||
Creative Commons may be contacted at https://creativecommons.org/.
|
||||
|
||||
----
|
||||
This project incorporates portions of the 'Ruby' project available
|
||||
under a '2-clause BSD' license.
|
||||
|
||||
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Apache HBase
|
||||
Copyright 2007-2020 The Apache Software Foundation
|
||||
Copyright 2007-2022 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
|
|
@ -56,6 +56,110 @@ module IRB
|
|||
# after all output.
|
||||
super unless @context.last_value.nil?
|
||||
end
|
||||
|
||||
# Copied from irb.rb and overrides the rescue Exception block so the
|
||||
# Shell::exception_handler can deal with the exceptions.
|
||||
def eval_input
|
||||
@scanner.set_prompt do
|
||||
|ltype, indent, continue, line_no|
|
||||
if ltype
|
||||
f = @context.prompt_s
|
||||
elsif continue
|
||||
f = @context.prompt_c
|
||||
elsif indent > 0
|
||||
f = @context.prompt_n
|
||||
else
|
||||
f = @context.prompt_i
|
||||
end
|
||||
f = "" unless f
|
||||
if @context.prompting?
|
||||
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
||||
else
|
||||
@context.io.prompt = p = ""
|
||||
end
|
||||
if @context.auto_indent_mode
|
||||
unless ltype
|
||||
ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
|
||||
indent * 2 - p.size
|
||||
ind += 2 if continue
|
||||
@context.io.prompt = p + " " * ind if ind > 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@scanner.set_input(@context.io) do
|
||||
signal_status(:IN_INPUT) do
|
||||
if l = @context.io.gets
|
||||
print l if @context.verbose?
|
||||
else
|
||||
if @context.ignore_eof? and @context.io.readable_after_eof?
|
||||
l = "\n"
|
||||
if @context.verbose?
|
||||
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
||||
end
|
||||
else
|
||||
print "\n"
|
||||
end
|
||||
end
|
||||
l
|
||||
end
|
||||
end
|
||||
|
||||
@scanner.each_top_level_statement do |line, line_no|
|
||||
signal_status(:IN_EVAL) do
|
||||
begin
|
||||
line.untaint
|
||||
@context.evaluate(line, line_no)
|
||||
output_value if @context.echo?
|
||||
exc = nil
|
||||
rescue Interrupt => exc
|
||||
rescue SystemExit, SignalException
|
||||
raise
|
||||
rescue Exception
|
||||
# HBASE-26741: Raise exception so Shell::exception_handler can catch it.
|
||||
# This modifies this copied method from JRuby so that the HBase shell can
|
||||
# manage the exception and set a proper exit code on the process.
|
||||
raise
|
||||
end
|
||||
if exc
|
||||
if exc.backtrace && exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
||||
!(SyntaxError === exc)
|
||||
irb_bug = true
|
||||
else
|
||||
irb_bug = false
|
||||
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
|
||||
m = sprintf("%9d: from %s", (count += 1), m)
|
||||
if messages.size < @context.back_trace_limit
|
||||
messages.push(m)
|
||||
elsif lasts.size < @context.back_trace_limit
|
||||
lasts.push(m).shift
|
||||
levels += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
attr = STDOUT.tty? ? ATTR_TTY : ATTR_PLAIN
|
||||
print "#{attr[1]}Traceback#{attr[]} (most recent call last):\n"
|
||||
unless lasts.empty?
|
||||
puts lasts.reverse
|
||||
printf "... %d levels...\n", levels if levels > 0
|
||||
end
|
||||
puts messages.reverse
|
||||
messages = exc.to_s.split(/\n/)
|
||||
print "#{attr[1]}#{exc.class} (#{attr[4]}#{messages.shift}#{attr[0, 1]})#{attr[]}\n"
|
||||
puts messages.map {|s| "#{attr[1]}#{s}#{attr[]}\n"}
|
||||
print "Maybe IRB bug!\n" if irb_bug
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
|
|
Loading…
Reference in New Issue