BetterErrors / better_errors

Better error page for Rack apps
MIT License
6.88k stars 437 forks source link

SimpleDelegator causes NameError (local variable `m' not defined for Binding object) #351

Closed pdobb closed 4 years ago

pdobb commented 8 years ago

I've just updated my app to Ruby 2.2.4, Rails 4.2, and BetterErrors 2+ with BindingOfCaller.

Whenever an error occurs in my application, I'm seeing the left side of the BetterErrors page, but not the right side with the live shell. Then, if I look in the server log I see the following. (I do not have this problem if I downgrade to BetterErrors v 1.1.0 with BindingOfCaller at same version).

NameError (local variable m' not defined for #<Binding:0x007f9d0fb1ede8>): /Users/a01223/.gem/ruby/2.2.4/bundler/gems/better_errors-d285ecf7f789/lib/better_errors/stack_frame.rb:73:inlocal_variable_get'

I added a debugger in my local copy of the gem and see:

From: /Users/a01223/.gem/ruby/2.2.4/gems/better_errors-2.1.1/lib/better_errors/stack_frame.rb @ line 74 BetterErrors::StackFrame#local_variables:

    69: def local_variables
    70:   return {} unless frame_binding
    71:   frame_binding.eval("local_variables").each_with_object({}) do |name, hash|
    72:     if defined?(frame_binding.local_variable_get)
    73:       binding.pry
 => 74:       hash[name] = frame_binding.local_variable_get(name)
    75:     else
    76:       hash[name] = frame_binding.eval(name.to_s)
    77:     end
    78:   end
    79: end

[1] r2.2.4 pry(<...>.rb:78:in `block in <...>'):0 > frame_binding.local_variable_get(name)
NameError: local variable `m' not defined for #<Binding:0x007f93678cbc50>
from (pry):2:in `local_variable_get'
[2] r2.2.4 pry(<...>.rb:78:in `block in <...>'):0 > frame_binding.eval("local_variables")
=> [:m, :args, :block, :r, :target]

I have no idea where these local_variables are coming from. But none of them appear to be accessible. If I just wrap lines 72..77 in a rescue NameError block that does nothing my problem goes away.

I'm not sure why I get this issue and not others. Any thoughts on why these local_variables ([:m, :args, :block, :r, :target]) are "there" but "not there"?

pdobb commented 8 years ago

I'm closing this because my issue has resolved itself. I'm not sure how exactly... but I just continued updating gems, environment config files etc as part of my Rails 4.2 upgrade (from Rails 3.2) and eventually the error went away.

jrochkind commented 7 years ago

I am having this issue with byebug 9.0.6, without better_errors being involved at all. This is the only google hit. Very mysterious. Same "local variable 'm' not defined". No idea what's up with m.

pdobb commented 7 years ago

@jrochkind I ran into this a few times since my original issue, recorded above. I don't remember exactly what causes it, though I feel like I had it figured out at some point. For what it's worth, I'm also running byebug 0.9.6. Sorry I couldn't be more help. Will try to report back if it dawns on me what it was.

glebtv commented 6 years ago

This seems to be a strange bug in binding_of_caller when using SimpleDelegator class or something like that. Happens for me in active admin page with nested form. This is my workaround that lets the better_errors page still show up without the variables it can't resolve: https://github.com/glebtv/better_errors/commit/6d00365df24eb5660ab32be16728089f7fa1ae13

pdobb commented 6 years ago

Reopening because this issue has been confirmed by others and the workaround proposed by doing @glebtv helps.

RobinDaugherty commented 6 years ago

@glebtv can you open a pull request for that change?

pdobb commented 6 years ago

Note, I solved this same issue in a very similar way in the Honeybadger gem. And it was due to SimpleDelegator as well. See: https://github.com/honeybadger-io/honeybadger-ruby/pull/207

pdobb commented 6 years ago

One final note for future reference:

Basically any object that inherits from SimpleDelegator will include those local variables and will have the above problem.

SimpleDelegator.new(Object.new).local_variables
=> [:m, :args, :block, :r, :target]
RobinDaugherty commented 4 years ago

Seems to have been fixed by #419