4

When I look for a problem, for example with a specific ActiveRecord object, I often find myself doing the following on my production system:

# RAILS_ENV=production bundle exec

irb(main)> article = Article.find(123)
=> #<Article id: 123, title: "Foobar">
irb(main)> article.do_something(3)
NoMethodError: undefined method `id' for nil:NilClass

Sometimes I can't reproduce, why the line article.do_something(3) throws an error, so I want to debug it directly on my server, in production mode.

The problem now is: How do I step into the method #do_something with the argument 3 on the object / instance article?

Of course, one could set a breakpoint in that method, reload production and let all their customers wait on that breakpoint till I'm done debugging... But that wouldn't be the best idea.

So, is there a way to debug into a method of a specific instance from a running irb / pry session? (both would be ok)

23tux
  • 14,104
  • 15
  • 88
  • 187

3 Answers3

10

After trying around and more googling, I think I found a solution that works for me.

  1. Log in to your rails console / irb / pry session
  2. Setup your case (e.g. load your models, require dependencies...), so that you can execute the code you want to debug in one line
  3. require 'byebug' (or require 'debugger' for older ruby versions)
  4. Now the interesting part: Put a debugger statement in front of the line you want to debug like this binding.pry; user.do_something or debugger; user.do_something
  5. Now you are in your debugger. Maybe you have to jump to the next line with next (or just n if you have shortcuts enabled) to step into your method.

Here is a complete example from our production system:

[1] pry(main)> require 'byebug'
=> true
[2] pry(main)> user = User.find(2)
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
=> #<User id: 2, name="XXX XXX">
[3] pry(main)> user.full_name
NameError: undefined local variable or method address for #<User:0x0055b168663590>

[4] pry(main)> binding.pry; user.full_name

[68, 73] in /usr/src/app/app/models/user.rb
   68:   end
   69: 
   70:   def full_name
=> 71:     "#{address.firstname} #{address.last_name}"
   72:   end
   73: end
(byebug) 
23tux
  • 14,104
  • 15
  • 88
  • 187
  • Sorry if I sound like an a-hole but the most likely explanation here is that you have forgot to run a migration in production. If you find that you have a hard time remembering to run migrations (we all do) you can use a post commit hook which runs `rake db:status` as a reminder. – max Apr 21 '16 at 11:53
  • 2
    The error was just for demonstration purpose, it's not a real error. The question was about how the get into that method with a debugger from an irb / pry / rails console context – 23tux Apr 21 '16 at 11:59
  • Very clever, love it! – Kazim Zaidi Mar 16 '17 at 14:40
  • Do not do this. Both Pry and Byebug come with stark warnings that there are serious security issues with using them in production. – max Apr 28 '22 at 15:16
1

sure pry, byebug, etc. are awesome BUT you don't need a gem

Ruby 3 (and newer versions of Ruby 2.x) has irb debugging built in

require 'irb'

def run
  a = "hello"
  binding.irb # debug starts here, eg puts a
  a = "something else"
  a
end

run
equivalent8
  • 13,754
  • 8
  • 81
  • 109
-2

You can use pry-debugger (through ruby 1.9.3) or pry-byebug (Ruby >= 2).

Both of these allow you to set breakpoints allowing you to interactively step through your code as it runs, inspecting variable values, method return values, etc.

How you'll manage this with production data I'm not exactly sure, but this will allow you to debug a particular method.