ConradIrwin / pry-rescue

Start a pry session whenever something goes wrong.
MIT License
852 stars 49 forks source link

"ArgumentError: uncaught throw :breakout_nav" when trying to `up` #85

Closed wsny closed 9 years ago

wsny commented 9 years ago

Here is an example where this is failing.

#Gemfile
source "https://rubygems.org"

gem 'pry'
gem 'pry-byebug'
gem 'pry-rescue'
gem 'pry-stack_explorer'
#code
def make_fail
  raise "an error"
  puts "boo"
end

make_fail

puts "yay"

When I run bundle exec rescue test.rb and try to run up to get up the stack, and I get:

ArgumentError: uncaught throw :breakout_nav from /home/WilliamSnyders/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/pry-byebug-3.1.0/lib/pry/commands/frames.rb:73:in 'throw'

I've had some issues tracking this down, cause pry warn's on the error somewhere and I can't seem to get the full stacktrace for it (probably didn't try hard enough). Though I do think I might see why this is happening.

For whatever reason, pry is getting called here with a hash:

# from ->  pry-rescue/lib/pry-rescue.rb
...
    def enter_exception_context(exception)
      ...
        if defined?(PryStackExplorer)
          pry :call_stack => bindings,
              :hooks => pry_hooks(exception),
              :initial_frame => initial_frame(bindings)
        else
          ...

https://github.com/ConradIrwin/pry-rescue/blob/master/lib/pry-rescue.rb#L58

Calling with the hash will call Pry with PryRescue instead of the binding of where the rescue happened

# from  ->   pry/lib/pry/core_extensions.rb
  def pry(object=nil, hash={})
    if object.nil? || Hash === object
      Pry.start(self, object || {})
    else
      Pry.start(object, hash)
    end
  end

https://github.com/pry/pry/blob/master/lib/pry/core_extensions.rb#L41-L47

And doing that means that pry-byebug thinks it should not involved (only wants to work with Bindings)

# from ->   pry-byebug/lib/pry-byebug/pry_ext.rb
class << Pry
  alias_method :start_without_pry_byebug, :start
  attr_reader :processor

  def start_with_pry_byebug(target = TOPLEVEL_BINDING, options = {})
    @processor ||= Byebug::PryProcessor.new

    if target.is_a?(Binding) && PryByebug.file_context?(target)
      # Wrap processor around the usual Pry.start to catch navigation commands
      @processor.start
    else
      # No need for the tracer unless we have a file context to step through
      start_without_pry_byebug(target, options)
    end
  end
  alias_method :start, :start_with_pry_byebug
end

https://github.com/deivid-rodriguez/pry-byebug/blob/master/lib/pry-byebug/pry_ext.rb#L7-L17

Which means we miss out on all the goodies of pry-byebug (like the catch for the :breakout_nav https://github.com/deivid-rodriguez/pry-byebug/blob/master/lib/byebug/processors/pry_processor.rb#L41)

Not sure why it was done this way, so didn't try to fix it myself.

wsny commented 9 years ago

Sorry, this actually seems to be a compatability thing with pry-byebug and pry-stack_explorer

wsny commented 9 years ago

This started with deivid-rodriguez/pry-byebug#55. pry-byebug now wants to handle moving around the frames now, but pry-rescue is trying to go around pry-byebug.