How I stopped worrying and learned to love errno.h

I just spent 16 hours debugging a complicated, annoying and frustrating problem involving pages not loading in a database frontend, and being spontaneously logged out of a webmail application.

The culprit was the SQLite library (or its bindings to Ruby) being useless with error messages. An example:

#<SQLite3::CantOpenException: could not open database: unable to open database file>

This is not okay. First off, not saying what file is a little annoying, but thankfully, I can tell which file by context since this program only opens one database. Second, and most grievous, it doesn’t say which system call failed (though I guess it’s open(2)) and third, it doesn’t say what error code. There’s a reason errno.h exists, people! perror is your friend. A happy little “It didn’t work” exception is no replacement for an exception that could read like this: #<SQLite3::CantOpenException: could not open database important.db: EMFILE: The process already has the maximum number of files open.>

I wouldn’t be hacking about supposing it’s a concurrency and locking issue. I’d be knowing that something’s not closing files like it’s supposed to, like I now know after stracing the process and seeing the real value of errno(3).

Don’t do this, folks! Let exceptions carry the most information possible. If you code in C, use perror(3).

Now I get to see why my web framework isn’t closing the database on a reload.