Debugging
The tools of the trade in Ruby/Rails
Megan Bowra-Dean
@megahbite
What is debugging?
- The act of finding "bugs" or defects in code and removing them.
- Popularised as a term by Grace Hopper when she found a moth in a mainframe.
Why do we need to debug?
- Machines do exactly what we tell them, and we're not perfect.
- Even if we're perfect, someone else might not be.
- Something is inevitably going to go wrong and our users will want it fixed.
So what do we do when we see this?
Or this?
Or even this?
Techniques, Tools and Concepts
Print debugging
- Only when we're really desperate.
- Generally only used these days in embedded systems (e.g. appliances)
Code
puts "We're about to do something that may be wrong"
this_function_doesnt_exist()
puts "We might not reach here"
Output
We're about to do something that may be wrong
./print_debugging.rb:4:in `': undefined method `this_function_doesnt_exist' for main:Object (NoMethodError)
Stack traces
-
Instead of relying on us putting
print
or
puts
statements in our code everywhere, stack traces tell us exactly where our code broke.
-
Provides more context to us, allowing us to better decipher error messages.
NoMethodError - undefined method `edit_notes_investment_path' for #<#<Class:0x007f8d00b33168>:0x007f8d0d351e10>:
actionpack (4.0.5) lib/action_dispatch/routing/polymorphic_routes.rb:129:in `polymorphic_url'
actionpack (4.0.5) lib/action_dispatch/routing/polymorphic_routes.rb:135:in `polymorphic_path'
app/helpers/campaigns_helper.rb:36:in `campaign_actions'
app/datatables/investments_datatable.rb:2:in `campaign_actions'
app/datatables/investments_datatable.rb:22:in `block in data'
draper (1.3.0) lib/draper/delegation.rb:10:in `map'
app/datatables/investments_datatable.rb:20:in `data'
app/datatables/investments_datatable.rb:13:in `as_json'
activesupport (4.0.5) lib/active_support/json/encoding.rb:50:in `block in encode'
activesupport (4.0.5) lib/active_support/json/encoding.rb:81:in `check_for_circular_references'
activesupport (4.0.5) lib/active_support/json/encoding.rb:49:in `encode'
activesupport (4.0.5) lib/active_support/json/encoding.rb:34:in `encode'
activesupport (4.0.5) lib/active_support/core_ext/object/to_json.rb:16:in `to_json'
actionpack (4.0.5) lib/action_controller/metal/renderers.rb:90:in `block in <module:Renderers>'
Debug logs
- Log all console output into a file that we can examine for unexpected output.
- Where you'll often find stack traces from exceptions/errors
- In Rails projects will can be found in the "log" folder
Interactive consoles
- Common feature with dynamic languages like Python, Ruby, Node.js etc.
- Allow you to run a statement at a time and change parameters around to see what works
-
irb
is built into Ruby,
pry
is a much better alternative.
-
Most often encountered by Rails programmers when running
rails console
Debuggers
- Debuggers are one of the most important tools in our toolbelt.
- Allow us to set "breakpoints" in code that will pause a running program.
- When a breakpoint statement or mark is hit we can then examine the current state of the program.
- Often drop into an interactive console as talked about previously.
-
In Ruby/Rails is provided by the
debugger
gem in Ruby versions < 2.0 and the
byebug
gem in Ruby versions >= 2.0
Less Common or Ruby/Rails Specifc Tools
Online Error Tracking/Reporting Tools
- When we deploy our apps to a production system we often turn off a lot of debugging output or may not have access to logs
- Online tools like Raygun allow us to keep track of errors that occur in production.
- Includes our useful stack traces and also other program state.
- Can notify you through numerous communication channels
Raygun.io
"Better Errors"
Better Errors is a gem for Rails that provides a better error page in your development environment.
Some things to think about
-
How do we debug when the code is not running on our machine? — remote debugging
- How do we debug code that isn't our own?
- How do we debug when the code isn't available? (the difficulty is this is one reason why Open Source is so important)