#402 Better Errors & RailsPanel
In this episode we’ll take a look at a couple of different tools that can help us in development. To demonstrate this we have a Rails application that manages projects. The page that lists the projects works but when we click a link to view a single project we get an error message.
It seems that we have an undefined
empty? method being called on
nil and that this error happens when we try to create a checkbox. There’s no obvious place in the source code that’s displayed that calls
empty? and it seems that this exception page could be improved to give us a better idea as to where the error is thrown.
Using Better Errors
That brings us to the first tool we’ll show in this episode: Better Errors. This makes the error pages much more useful and makes them look better, too. Let’s try it in our application.
When we add this gem to our app it’s important to place it in the
development group so that we don’t show details of any of our application’s errors in production. As ever we’ll need to run
bundle afterwards in order to install the gem.
group :development do gem 'better_errors' end
If we restart then server then reload the page Better Errors will handle the error and we’ll see exactly where the error has occurred.
The relevant source code is now nicely syntax-highlighted and we can see the
empty? method that is causing the problems. Above this source code is a stack trace and we can click any line of this to see the source code for that part of the stack. We can also look at the entire Rails app and view the source code for any part of the Rails source code or any gems that are part of the stack trace for the error.
A useful side-effect of this is that it helps us to get a better understanding of how Rails works. For our error we can see that the
check_box method is triggered in our code and working through the stack trace we’ll see that this method is called on a form builder and we can carry on and go through every step in the process to get a better understanding of what’s going on. At the bottom of the error page we’ll see information about the request including the parameters and any cookies that are used. This isn’t all that this gem can do, though. If we look at the error page we’ll see a tip to add a gem called
binding_of_caller which gives more functionality so let’s give that a try. Again, this gem should go in the development group and again we’ll need to run
bundle to install it.
group :development do gem 'better_errors' gem 'binding_of_caller' end
Make sure you’re on a trusted network if you’re going to use this gem as you don’t want malicious users accessing your Rails application this way. When we restart the app and reload the page again we get a lot more information including the local and instance variables.
nil which is why we’re getting an exception raised when we call
empty? on it.
empty? we should be calling
present? and to make this change we can click the name of the file which will open it up in a text editor. We’ll just make the change here but in a real application we’d write a failing test first to ensure that this bug is fixed and doesn’t recur.
Using Better Errors With AJAX Requests
Our application has another bug. If we mark a task as complete by checking its checkbox it should be automatically moved to the “Completed Tasks” section and its record updated in the database, all this being done by an AJAX request. When we do this, however, the task isn’t moved and if we look in the development log we’ll see than an exception was raised during the AJAX request. It would be better if we could see this exception and interact with it through Better Errors and we can by visiting the path
This shows us the last exception to occur and it matches the error in the development log. If we use the console to get the value of the value variable we’ll see that it’s a string containing the value “1”. This explains why we get an exception when we call
zero? on this value as we need to convert this to an integer first. Again we can open up the relevant file in our text editor by clicking the link and we can then fix this error. Now when we mark a task as complete it’s moved correctly to the other list.
Before we finish our look at Better Errors we’ll mention a couple of things about the link that opens up a text editor. This works with internal gem pages too so if we want to know how, say,
assign_attributes works in ActiveRecord we can click the link just like we would for our own source code. If we want to change the editor that Better Errors uses we can do so by creating a new initializer file in our application and setting the
BetterErrors.editor = :sublime if defined? BetterErrors
There are several different values we can set this to such as :sublime for Sublime Text. Note that we check that
BetterErrors is defined before setting this. The RDocs have more information about this and they show that we can use a string or even a proc object if we need a more customized solution.
The other tool we’ll take a look at is called Rails Panel. This is an extension for Chrome which adds a development log within the browser. This can be installed via the Chrome Web Store, although we also need to add a gem to our application called Meta Request. As with the other gems we’ve used this should go in the
development group and we we’ll need to run
bundle to install it.
group :development do gem 'better_errors' gem 'binding_of_caller' gem 'meta_request' end
Now, after restarting our application, we can open Chrome’s developer panel and we should see a new RailsPanel tab. As we visit various pages in our application we should see an entry for each one in the panel. This works for AJAX requests, too.
This panel contains all sorts of details about each request, including the format, how long it took to process, what the parameters were, what database queries were made and which views were rendered. As with Better Errors we can click on a view to open it up in a text editor. To customize the editor that’s used we need to open the Chrome preferences and we can choose between TextMate, MacVim or Sublime Text.
This is a fairly simple tool but it’s useful to have all of this information inline in the browser instead of having to look in a separate log.