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.
|
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.
|
under a '3-clause BSD' license.
|
||||||
|
|
||||||
Copyright 2008, Google Inc.
|
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.
|
this trademark restriction does not form part of this License.
|
||||||
|
|
||||||
Creative Commons may be contacted at https://creativecommons.org/.
|
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
|
Apache HBase
|
||||||
Copyright 2007-2020 The Apache Software Foundation
|
Copyright 2007-2022 The Apache Software Foundation
|
||||||
|
|
||||||
This product includes software developed at
|
This product includes software developed at
|
||||||
The Apache Software Foundation (http://www.apache.org/).
|
The Apache Software Foundation (http://www.apache.org/).
|
||||||
|
|
|
@ -56,6 +56,110 @@ module IRB
|
||||||
# after all output.
|
# after all output.
|
||||||
super unless @context.last_value.nil?
|
super unless @context.last_value.nil?
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
Loading…
Reference in New Issue