Throughout the development process you'll probably be very familiar with this (error) screen. You're going to see errors come up all over the place as you're developing something. You make a typo or something isn't working properly, or a gem just doesn't integrate well, so you'll get really familiar with this screen and it's nice because it tells you what line and what file that it's in, so you can kind of get an idea of what's going on, you can get an environment dump and it gives you a little bit of information that helps you figure out what was wrong. And in this episode, I'm going to talk about how we can improve this process to do a whole lot more work quickly by going through these errors without having to deal with this and jumping back into our code and back and forth, and printing out variables in the console or whatever.
So the gem we want to talk about today is called better errors, and better errors as a replacement for the red and white screen that we were just on for rails and other rack applications. So instead, you'll get this error screen and it has a lot of different features, so it breaks down everything that happened in your application and you can go through that. So you can into the internals of what rails was doing before it got into the code that crashed, so it's extremely helpful for building software and debugging errors and we're going to go talk about installing that next.
You want to use this in almost every single application that you have but you need to be extremely careful that this only available in development mode. If you make this available in production anyone could run any ruby code on your server which is very very bad. So people could delete anything they wanted if this was enabled in production. So I'm going to go walk you through this and the first step is going to be going over to rubygems and we'll look out better_errors, and then grab the Gemfile line and we'll go to our Gemfile inside of our application, we'll add
gem "better_errors", "~> 1.1.0"
And the other gem that we want to add is binding_of_caller, and this allows us to inspect the variables inside the application when it crashes, and this is really the tool that makes that screen so helpful, so we'll come back to our gemfile and paste in binding_of_caller but we want to be extremely careful that we put these in the development group so that they're only available in development mode, and then we can go back to our terminal and run
bundle install and if we come back to our Rails server, you want to restart that and now if you refresh your Rails application, you'll get the new error's screen.
So the binding_of_caller bit of this allows you to type here in this command, so you can run any Ruby commands just like you would in IRB, so you can say
puts "Hello", and it gives you proper Ruby command line here, so here we can go and see we can inspect the books variable, and we have a relation I don't have any books in the database so there's none, and then you can also replicate the error with current user, so I can inspect everything that's going on, and that's why the binding_of_caller piece here is so important. In the regular better_errors, it allows you to jump back down, all the way down the stack inside of Rails itself, to learn how this whole request is started and how it actually got to the point where it was, so you can see that for a while, it's doing work inside of the books controller, but before that it starts to do active support things, and then you can even get into the routing in any of the rack middleware before that like the cookies in the session store.
But really the piece that we're concerned with is the ones in the application frames, because that means that code here that went wrong was inside of our application. If you're running a problem with a gem, you'll be able to go into all frames and see the code that was inside your application that might have caused the gem to break, and you can kind of inspect the gem and see what it's looking for and why your code may have broke.
Better errors is something that I would recommend in absolutely every application that you build in Rails and I'm sure that in the next few episodes, we're going to take a look at some things that will break and we'll be able to inspect what went wrong using this tool.
Transcript written by Miguel
I'm running into an issue when installing binding_of_caller. When I run bundle install I get the following error An error occurred while installing debug_inspector (0.0.2), and Bundler cannot continue. Make sure that `gem install debug_inspector -v '0.0.2'` succeeds before bundling. I'm not sure how to get around this. Any ideas?
Interesting. I haven't had trouble with that gem before. Did it give you any more text for the error?
Thanks for the reply. Here's the total output:
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
linking shared-object debug_inspector.bundle
clang: error: unknown argument: '-multiply_definedsuppress' [-Wunused-command-line-argument-hard-error-in-future]
clang: note: this will be a hard error (cannot be downgraded to a warning) in the future
make: *** [debug_inspector.bundle] Error 1
Gem files will remain installed in /Users/ryan.dagostino/.bundler/tmp/17652/gems/debug_inspector-0.0.2 for inspection.
Results logged to /Users/ryan.dagostino/.bundler/tmp/17652/gems/debug_inspector-0.0.2/ext/debug_inspector/gem_make.out
An error occurred while installing debug_inspector (0.0.2), and Bundler cannot
Make sure that `gem install debug_inspector -v '0.0.2'` succeeds before
That sounds like your compiler is too old maybe. I'm not sure the best solution there. What version of your OS are you on and what version of Ruby are you using?
Hopefully it's not my computer running OS X 10.9 and Ruby version 2.0.0p247. You think it just needs an upgrade to the Ruby version?
Thanks for the help Chris. Regardless better errors is working. Great tutorial by the way.
When Rails 5 came out Better Errors was incompatible. Not sure if works with Rails 5 now. But anyway I began using the web-console gem in the development environment instead and it's actually better. It provides the same IRB console when you get an error but you can also insert the console anywhere in your app by adding 'console' in the controller action or <%= console %> in the view. And you don't need to also install binding_of_caller.