Rails: When an Uninitialized Constant Hits the Vent
Last two weeks I was seeing the production server of one of my clients hit the same error over and over with no visible pattern. This second it works, the next it fails and leaves the Mongrel cluster in an undefined state somewhere between this world and hell.
The error I’m referring to is:
NameError (uninitialized constant MyModule::Utils::NetSession)
... backtrace follows ...
I need to repeat that it comes and goes under some non-obvious circumstances, and is hard to recreate. Fortunately, I found the solution and here’s what it was.
I have a directory hierarchy like below. I’m sure when you see it, it all becomes obvious and simple, but it wasn’t for me at that time as there were many files that I omitted below.
/lib
/my_module
klass1.rb
...
utils.rb
/utils
net_session.rb
The piece of code in klass1 that failed looks as follows:
def new_session
Utils::NetSession.new
end
Simple, heh.
utils.rb
is a helper module which is included into MyModule
, but apparently loaded only when really necessary (it’s the only explanation why it didn’t fail all the time, as you will see). When it is loaded and included, the MyModule::Utils
becomes defined, and Utils::NetSession
resolution starts to fail. It happens as Rails begins looking for Utils
name space from MyModule
, finds MyModule::Utils
and doesn’t find any NetSession
there. That’s pretty much all to it.
The solutions are:
- Either rename utils.rb (which I did in favor of utilities.rb), or
- Use
::Utils::NetSession.new
(which is not safe as one day you can forget about the leading::
, and get back to roots)
Hope this helps someone like me fighting the way through these extremely infrequent but painful Rails gotchas.