Project

General

Profile

Actions

Feature #14835

closed

Support TracePoint#raised_exception on non-:raise events

Added by tagomoris (Satoshi TAGOMORI) over 4 years ago. Updated 10 months ago.

Status:
Feedback
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:87454]

Description

TracePoint supports :raise and :return events, and :return event will be invoked when an exception occurs in a method.
But its TracePoint block parameter instance doesn't have any information about raised exceptions.

That means, we can know an exception was raised in a method, but we cannot know an exception was rescued or not there.

def thrower
  raise "exception"
end

def caller_without_rescue
  thrower
end

tp = TracePoint.trace(:raise, :return) do |tp|
  case tp.event
  when :raise
    p(here: "trace", event: :raise, klass: tp.defined_class, method: tp.method_id, exception: tp.raised_exception)
  else
    p(here: "trace", event: tp.event, klass: tp.defined_class, method: tp.method_id, value: tp.return_value)
  end
end


caller_with_rescue

puts "\n----------------------\n"

begin
  caller_without_rescue
rescue => e2
  puts "outer rescue: #{e2}"
end

The script above shows these events, but TracePoint events are completely same in these two examples.

# caller_with_rescue
{:here=>"trace", :event=>:raise, :klass=>Object, :method=>:thrower, :exception=>#<RuntimeError: exception>}
{:here=>"trace", :event=>:return, :klass=>Object, :method=>:thrower, :value=>nil}
rescue: exception
{:here=>"trace", :event=>:return, :klass=>Object, :method=>:caller_with_rescue, :value=>nil}

----------------------
# caller_without_rescue
{:here=>"trace", :event=>:raise, :klass=>Object, :method=>:thrower, :exception=>#<RuntimeError: exception>}
{:here=>"trace", :event=>:return, :klass=>Object, :method=>:thrower, :value=>nil}
{:here=>"trace", :event=>:return, :klass=>Object, :method=>:caller_without_rescue, :value=>nil}
outer rescue: exception

My expectation is that TracePoint instance should contain exception instance in raised_exception at the time when it's not rescued.

Updated by jeremyevans0 (Jeremy Evans) over 1 year ago

  • Tracker changed from Bug to Feature
  • Subject changed from Impossible to know whether an exception was rescued or not using TracePoint to Support TracePoint#raised_exception on non-:raise events
  • ruby -v deleted (ruby 2.6.0preview2 (2018-05-31 trunk 63539) [x86_64-darwin17])
  • Backport deleted (2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN)

I looked into this, and with the current TracePoint design, it does not appear possible. For :raise events, the raised_exception is stored in trace_args->data. This is the same location that the return value is stored for :return, :c_return, and :b_return events. To change this, we would have to modify rb_trace_arg_struct to support additional space for storing the exception in the non-:raise case, and I'm not sure at the point of :return (or :c_return/:b_return) if we can get the exception.

TracePoint#raised_exception is documented to only work for :raise events and not other events. So the current behavior is not a bug. I agree that there may be cases where raised_exception would be useful in other events. So I'm switching to feature request, though I don't know if it is feasible to implement such a feature.

Updated by ko1 (Koichi Sasada) 10 months ago

  • Status changed from Open to Feedback

Sorry I can't understand the request.
Could you explain more?

Updated by tagomoris (Satoshi TAGOMORI) 10 months ago

We cannot know how "return" events are triggered. It can be triggered by usual returns (return values), and also be triggered by raised exceptions (does not return values).
This also makes it impossible to know where the raised exception was rescued.

If the "return" event contains exceptions (as raised_exception) when it is triggered by raised events, we can distinguish "return" events, by usual returns, or by raised exceptions. That is my request.

Currently, calling raised_exception method on "return" event causes the exception below:

<internal:trace_point>:338:in `raised_exception': not supported by this event (RuntimeError)
	from /Users/tagomoris/hoge.rb:20:in `block in <main>'
	from /Users/tagomoris/hoge.rb:9:in `caller_with_rescue'
	from /Users/tagomoris/hoge.rb:26:in `<main>'
Actions

Also available in: Atom PDF