mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
config: factor out exception_handler hook to a separate class
This commit is contained in:
parent
9306e69bda
commit
95d3a74e9b
4 changed files with 107 additions and 22 deletions
|
@ -21,6 +21,7 @@ require 'pry/syntax_highlighter'
|
|||
require 'pry/editor'
|
||||
require 'pry/history'
|
||||
require 'pry/color_printer'
|
||||
require 'pry/exception_handler'
|
||||
|
||||
Pry::Commands = Pry::CommandSet.new unless defined?(Pry::Commands)
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ class Pry
|
|||
# @return [Pry::Config]
|
||||
# An object who implements the default configuration for all
|
||||
# Pry sessions.
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def self.defaults
|
||||
defaults = from_hash(
|
||||
input: Pry.lazy { lazy_readline(defaults) },
|
||||
|
@ -18,26 +17,7 @@ class Pry
|
|||
prompt_safe_contexts: Pry::Prompt::SAFE_CONTEXTS,
|
||||
print: Pry::ColorPrinter.method(:default),
|
||||
quiet: false,
|
||||
|
||||
# Will only show the first line of the backtrace
|
||||
exception_handler: proc do |output, exception, _|
|
||||
if exception.is_a?(UserError) && exception.is_a?(SyntaxError)
|
||||
output.puts "SyntaxError: #{exception.message.sub(/.*syntax error, */m, '')}"
|
||||
else
|
||||
output.puts "#{exception.class}: #{exception.message}"
|
||||
output.puts "from #{exception.backtrace.first}"
|
||||
|
||||
if exception.respond_to? :cause
|
||||
cause = exception.cause
|
||||
while cause
|
||||
output.puts "Caused by #{cause.class}: #{cause}\n"
|
||||
output.puts "from #{cause.backtrace.first}"
|
||||
cause = cause.cause
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
exception_handler: Pry::ExceptionHandler.method(:handle_exception),
|
||||
unrescued_exceptions: [
|
||||
::SystemExit, ::SignalException, Pry::TooSafeException
|
||||
],
|
||||
|
@ -113,7 +93,6 @@ class Pry
|
|||
exec_string: ""
|
||||
)
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
def self.shortcuts
|
||||
Convenience::SHORTCUTS
|
||||
|
|
41
lib/pry/exception_handler.rb
Normal file
41
lib/pry/exception_handler.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
class Pry
|
||||
# @api private
|
||||
# @since ?.?.?
|
||||
module ExceptionHandler
|
||||
class << self
|
||||
# Will only show the first line of the backtrace.
|
||||
def handle_exception(output, exception, _pry_instance)
|
||||
if exception.is_a?(UserError) && exception.is_a?(SyntaxError)
|
||||
output.puts "SyntaxError: #{exception.message.sub(/.*syntax error, */m, '')}"
|
||||
else
|
||||
output.puts standard_error_text_for(exception)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def standard_error_text_for(exception)
|
||||
text = exception_text(exception)
|
||||
return text unless exception.respond_to?(:cause)
|
||||
|
||||
cause = exception.cause
|
||||
while cause
|
||||
text += cause_text(cause)
|
||||
cause = cause.cause
|
||||
end
|
||||
|
||||
text
|
||||
end
|
||||
|
||||
def exception_text(exception)
|
||||
"#{exception.class}: #{exception.message}\n" \
|
||||
"from #{exception.backtrace.first}\n"
|
||||
end
|
||||
|
||||
def cause_text(cause)
|
||||
"Caused by #{cause.class}: #{cause}\n" \
|
||||
"from #{cause.backtrace.first}\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
64
spec/exception_handler_spec.rb
Normal file
64
spec/exception_handler_spec.rb
Normal file
|
@ -0,0 +1,64 @@
|
|||
RSpec.describe Pry::ExceptionHandler do
|
||||
describe ".handle_exception" do
|
||||
let(:output) { StringIO.new }
|
||||
let(:pry_instance) { Pry.new }
|
||||
|
||||
context "when exception is a UserError and a SyntaxError" do
|
||||
let(:exception) do
|
||||
SyntaxError.new('cool syntax error, dude').extend(Pry::UserError)
|
||||
end
|
||||
|
||||
it "prints the syntax error with customized message" do
|
||||
described_class.handle_exception(output, exception, pry_instance)
|
||||
expect(output.string).to start_with("SyntaxError: dude\n")
|
||||
end
|
||||
end
|
||||
|
||||
context "when exception is a standard error" do
|
||||
let(:exception) do
|
||||
error = StandardError.new('oops')
|
||||
error.set_backtrace(["/bin/pry:23:in `<main>'"])
|
||||
error
|
||||
end
|
||||
|
||||
it "prints standard error message" do
|
||||
described_class.handle_exception(output, exception, pry_instance)
|
||||
expect(output.string)
|
||||
.to eq("StandardError: oops\nfrom /bin/pry:23:in `<main>'\n")
|
||||
end
|
||||
end
|
||||
|
||||
context "when exception is a nested standard error" do
|
||||
let(:exception) do
|
||||
error = nil
|
||||
begin
|
||||
begin
|
||||
raise 'nested oops'
|
||||
rescue # rubocop:disable Style/RescueStandardError
|
||||
raise 'outer oops'
|
||||
end
|
||||
rescue StandardError => outer_error
|
||||
error = outer_error
|
||||
end
|
||||
|
||||
error
|
||||
end
|
||||
|
||||
before do
|
||||
if RUBY_VERSION.start_with?('1.9', '2.0')
|
||||
skip("Ruby #{RUBY_VERSION} doesn't support nested exceptions")
|
||||
end
|
||||
end
|
||||
|
||||
it "prints standard error message" do
|
||||
described_class.handle_exception(output, exception, pry_instance)
|
||||
expect(output.string).to match(
|
||||
/RuntimeError:\souter\soops\n
|
||||
from\s.+\n
|
||||
Caused\sby\sRuntimeError:\snested\soops\n
|
||||
from.+/x
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue