lib/ensure_it/errors.rb in ensure_it-0.1.1 vs lib/ensure_it/errors.rb in ensure_it-0.1.2
- old
+ new
@@ -60,23 +60,24 @@
end
def self.raise_error(method_name, message: nil, error: Error, **opts)
error = Error unless error <= Exception
error_msg = ErrorMessage.new(method_name, message, caller[1..-1])
- if opts.key?(:smart) && opts[:smart] != true ||
- EnsureIt.config.errors != :smart
- raise error, error_msg.message, error_msg.backtrace
+ # save message in backtrace in variables to not call getter
+ # methods of error_msg instance in raise call
+ error_message = error_msg.message
+ error_backtrace = error_msg.backtrace
+ if opts[:smart] == true || EnsureIt.config.errors == :smart
+ inspect_source(error_msg, **opts)
+ activate_smart_errors(error_msg, **opts)
end
- raise_smart_error(error_msg, error, **opts)
+ raise error, error_message, error_backtrace
end
- def self.raise_smart_error(error, error_class, **opts)
- inspect_source(error, **opts)
+ def self.activate_smart_errors(error, **opts)
tp_count = 0
error_obj = nil
- error_message = error.message
- error_backtrace = error.backtrace
#
# first trace point is to capture raise object before exitting
# from :ensure_* method
#
# after that with second trace point we try to return from :ensure_* method
@@ -86,34 +87,28 @@
# save error object for patching
error_obj = first_tp.raised_exception
else
# skip returns from :raise_smart_error and :raise_error
tp_count += 1
- if tp_count > 1
- # at this moment we are at end of 'ensure_' method
+ if tp_count > 2
first_tp.disable
- TracePoint.trace(:return) do |second_tp|
- # skip return from :ensure_* method
- tp_count += 1
- if tp_count > 3
- # now we are in caller context
- second_tp.disable
- unless error_obj.nil?
- # inspect caller code
- inspect_code(second_tp, error, **opts)
- # patch error message
- error_obj.extend(Module.new do
- @@ensure_it_message = error.message
- def message; @@ensure_it_message; end
- end)
- end
+ # at this moment we are at the end of 'ensure_' method
+ # skip last code line in :ensure_* method
+ TracePoint.trace(:return, :line) do |second_tp|
+ # now we are in caller context
+ second_tp.disable
+ unless error_obj.nil?
+ # inspect caller code
+ inspect_code(second_tp, error, **opts)
+ # patch error message
+ msg = error.message
+ error_obj.define_singleton_method(:message) { msg }
end
end
end
end
end
- raise error_class, error_message, error_backtrace
end
def self.inspect_source(error, **opts)
file_name, line_no = error.backtrace.first.split(':', 2)
return unless File.exist?(file_name)
@@ -166,8 +161,8 @@
end
end
line
end
- private_class_method :raise_smart_error, :inspect_source, :inspect_code,
+ private_class_method :activate_smart_errors, :inspect_source, :inspect_code,
:read_line_number
end