Something I would often tell my mentees was “Error messages are our friends”. This is because they would panic at the sight of an error message like it was the proclamation of impending doom. Calmly I would explain that the app already halted the code and is warning you of trouble. It’s trying to help you by sending you this message. The error message is not a threat, it’s a tool to help you find issues in your code.
There are a lot of thoughts that come when starting the developers journey, the most common one being “I’m a fraud” or “I don’t know what I’m doing”. When having thoughts like this it is easy to view an error message as a sign of how poor you are at your job. But this is not the case at all.
An error message exists because someone created it. Someone thought that what you did was likely to be done and wanted to help you figure out the issue sooner rather than later. If you get an error message, know that you are one of very many who’ve gotten it before; and that the creator of the message likely made the same mistake you did. You can think of it like a future you sending a message back in time to the current you to keep you from deploying code that silently fails.
Silent failures are the enemy. They leave you clueless, because your code doesn’t work and has no indication as to why. However silent failures are not a sign of you being a poor developer either. They are a sign of an edge case, a situation not accounted for. It’s very hard to account for everything. Once you solve the problem, you could go on to make a way to catch it when it happens and send a helpful message to another developer who will likely encounter this issue too. This is why I say “Error messages are our friends”. They are the voice of someone who dealt with a problem and hopes to now save us from the same struggle.
Found in Translation
After acknowledging that the error message was sent to help us, we move on to learning how to understand what it says. This takes time, documentation, perhaps reaching out to a co-worker or a stackoverflow where someone has already decoded it. Error messages are limited and usually need to be generic so that they can be reused for many purposes.
I usually start with the first line and think of it within the context of the code that triggered it. I can get more into context and how vital it is to meaning, but that is a blog post for another day. So just keep in mind that context is key. I once acted out an improv scene of a relationship falling apart where me and my scene partner were tasked with saying one line, over and over in different ways to convey deeper meaning. We were saying the same words the whole scene, but the meaning changed over the course of it. This same principle applies to error message language.
Here are some examples of error messages you may receive and how to decode them.
Error:
VCR::Errors::UnhandledHTTPRequestError:
Context:
I had made a stub for a test that calls on an API. I wanted the response from said API to be consistent for the test so I stubbed it. However I was getting an unhandled request error for that test. This unhandled request error happened remotely in CI but not locally. Making it harder to debug.
Investigation:
I checked the urls from the unhandled request and the stubbed request. They were the same. The format was also the same. As I moved through the request details I narrowed down the field of options to the API key. I had the key locally but it wasn’t in the system that runs tests remotely on the pull request. I needed to update my stub to not add the API key since it would be missing in CI.
The context was important. I needed to consider why a test that passes locally would fail in CI. What was the difference between the environments? The solution for this issue came from a co-worker, since I had to leave to go to an appointment. I very much appreciate their investigative work.
Error:
NoMethodError
undefined method `name' for nil:NilClass (NoMethodError)
Context:
The error occurred in this class’ author_name method
class Book
belongs_to :author
def author_name
author.name # <-- the error was here
end
end
The method uses the association with the author table to get the author’s name. In the author model there was this code:
class Author
has_many :books
end
Investigation:
Looking at the error it indicates that the author for the book was not found. Then looking at the author model it says the author has many books but does not say what to do with those books if the author record is deleted. In this case the author had been deleted but their books remained behind, no longer associated with any author.
The Future is Failure Clarity
Those were some basic and often seen error messages. They are fairly generic so they rely heavily on context. However, error messages are improving in how they communicate meaning. Now they are better able to direct you to the location of the issue and even sometimes highlight the specific part of a line that is causing problems.
The error_highlight gem for Ruby 3.1 helps show where errors happen. With it, this error:
a = {}
a[:foo][:bar][:baz]
# => undefined method `[]' for nil:NilClass (NoMethodError)
Now looks like this:
a = {}
a[:foo][:bar][:baz]
# => undefined method `[]' for nil:NilClass (NoMethodError)
# a[:foo][:bar][:baz]
# ^^^^^^
Text editors are getting better and better at highlighting syntax errors. I’ve struggled many times with locating an unmatched “end” or “}” but now I get handy highlighting when one has no matching beginning or vice versa.
In Ruby we went from Ruby < 3.2
a.rb:6: syntax error, unexpected `end', expecting end-of-input
To Ruby 3.2
Unmatched `end', missing keyword (`do', `def`, `if`, etc.) ?
1 class ClassName
2 def do_stuff
> 3 @stuff.each
> 4 end
5 end
6 end
test.rb:6: syntax error, unexpected `end' (SyntaxError)
I was so excited when I started getting code suggestions from error messages, so they were not only telling me something was wrong but also giving me a possible fix.
My friendship with error messages has been getting better and better as I learn how to understand what they are trying to say and as they get better at talking to me. Communication in a relationship is extremely important. I hope I have helped you have a healthy relationship with error messages.
I’d like to give a warm shout out to Matheus Richard for providing some examples and sharing some advances in error messaging.