Recovering from common Ruby on Rails errors and pitfalls (Part 1)

/ fix / rubyruby on railserrors

Ruby on Rails is great to give out detailed error messages. Additionally, there is a wealth of knownledge in the online community of other developers running into the exact same error and the reasons behind why they are occuring. Over the past couple months I have compiled 5 errors that I see most often.

  1. A server is already running. Check pids/
  2. bind: Address already in use - bind(2) for (Errno::EADDRINUSE)
  3. Terminal outputs rails console errors after stopping execution
  4. NameError at [route] uninitialized constant [class-name]
  5. MultiJson::ParseError at [route]. Oj::ParseError

A server is already running

What it looks like:

A server is already running. Check /Users/username/Rails/sourcing/tmp/pids/

What it means:

Occassionally, when halting or using ctrl+c to stop a rails server instance it will fail to unlock its process id. This will prevent you from starting a new server for the project as the server will think it is still running when it is in fact not.

How to fix it:

Remove the file from the project.

rm /tmp/pids/

Address already in use

What it looks like:

=> Booting WEBrick
=> Rails 4.2.4 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2015-10-03 14:00:40] INFO  WEBrick 1.3.1
[2015-10-03 14:00:40] INFO  ruby 2.2.1 (2015-02-26) [x86_64-darwin14]
/Users/jfrankel/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/socket.rb:206:in `bind': Address already in use - bind(2) for (Errno::EADDRINUSE)

What it means:

This error means that the port number you specified is still in use by another application or potentially an unclosed instance of your rails server. Typically the port Rails uses is 3000 so we need to make sure that there isn't another process already using it.

How to fix it:

List out all the processes using the port your Rails server is using (default 3000). Switch tcp:3000 to just tcp if you want to list all processes.

lsof -wni tcp:3000

You should receive an output that looks like this:

  ruby    41704 jfrankel   12u  IPv6 0xf3fe9a8ff1e035b9      0t0  TCP [::1]:hbci (LISTEN)
  ruby    41704 jfrankel   13u  IPv4 0xf3fe9a8ff6649a29      0t0  TCP (LISTEN)

Then all you need to do is kill the specific process based on its PID. You can supply multiple PID's to the kill method separated by a space each if there are additional processes that need to be stopped.

kill -9 41704

Rails console gives errors in terminal after closing with Ctrl+z

What it looks like:

jfrankel$ rails c
Loading development environment (Rails 4.2.4)
2.2.1 :002 >
[1]+  Stopped                 rails c
jfrankel$ ls
-bash: l: command not found

jfrankel$ ruby -v
-bash: uy-: command not found

jfrankel$ exit
NameError: undefined local variable or method `vei' for main:Object

What it means:

Rails console doesn't exit cleanly when you use ctrl+z. This is due to the fact that ctrl+z doesn't actually exit a command line program but instead pauses them. Because of this the commands in the terminal get all jumbled up.

How to fix it:

Typing the keyword exit or using the preferred stop command of ctrl+c will properly stop rails console, but this is only valid for the next time you run rails console. For now you will have to restart the current terminal session or just close the window and start a new terminal session up.

Name Error

What it looks like:

NameError at /awards/11
uninitialized constant User::NotificationSetting

What it means:

This is a farily straight forward error. Try re-reading the output error message and it starts to make sense. It is saying that there is an uninitalized constant, which could be a class or variable.

This most likely is a class and or variable name that has a typo in it or doesn't exist yet in this context.

How to fix it:

Make sure to double check spellings of classes and variables.

Additionally, something that can trip you up is to make sure the plurality of the constant is correct. Models are singular while controllers are plural.

MultiJson::ParseError with cookies

What it looks like:

MultiJson::ParseError at /login

What it means:

This error is indicating that some JSON is not being parsed correctly. In the case of cookies it could mean that the cookie doesn't exist or is an valid that is not able to be parsed.

How to fix it:

There are a couple of fixes for this issue. The easiest is to remove all cookies for the domain in question using chrome resource tab inside developer tools. This will force the cookies to be recreated.

Additionally, writing code that gracefully degrades to a default valid value could also fix it. For example adding an empty json array as a backup value as shown below. || "{}"
def preferences
  @_preferences ||= MultiJson.load(cookies["preferences_#{get_preference_group}"] || "{}")

Do you have a different solution to a common error I've listed here? Got another error you keep running into? Leave me a comment below. I'm looking forward to hearing from you.

Join the conversation

comments powered by Disqus