The Four Lines Every Caller Had To Remember

by Serguey Shinder

The page came at ten past nine on a Sunday. Order processing had stopped, and the stack trace pointed at a null pointer in a file somebody had added on the Friday, in a feature that had nothing to do with orders and was merely unlucky enough to share a path with them.

The line that threw called a method I had written three years earlier. It looked up an account by reference and returned the account. When there was no account, it returned null.

That was a deliberate choice and I remember making it. The alternative was throwing, and throwing felt wrong because a missing account is an ordinary situation rather than an exceptional one. Returning null was the quietest thing I could do, and I documented it. The comment above the method said in plain English that it returns null when no account matches, and it had said so accurately for three years.

What I had also done, without noticing, was create a small ritual. Every caller had to check the result, decide what a missing account meant in their context, log something so the absence was not silent, and carry on. Four lines, more or less the same four, at every call site. That Sunday there were twenty three of them. Twenty two had the ritual. One did not.

The person who wrote the twenty third had done nothing careless. They read the method name, saw that it returned an account, and wrote code that used an account. To find out otherwise they would have had to stop and read a comment about a case that does not arise in development, in testing, or in any demo.

That is the thing I got wrong, and it is not about null specifically. I had made a decision once, about what the absence of an account means, and then declined to express it in the code. Instead I exported it to every place that called me, where it had to be remembered by a different person on a different day under different pressure. A rule you can only follow by remembering it will be followed at whatever rate people remember things, and twenty three call sites is a lot of chances.

The fix was not to add a check. It was to change what the method gives you. There are two of them now. One returns a type that cannot be mistaken for an account and will not compile if you treat it as one. The other is for callers who genuinely cannot continue without the account, and it throws, with the reference in the message.

I now read my own interfaces looking for the ceremony they require. If the same four lines appear after every call, that is not discipline on my colleagues' part. It is a decision I refused to make, paid for by everyone else.

– Serguey Asael Shinder

Leave a Reply