Post

Rust Changed My Mind: Exceptions

Rust Changed My Mind: Exceptions

Exceptions are bad, m’kay?

One of the ways Rust changed my mind is that it increased my intolerance of exceptions to the same degree of contempt I feel for inheritance and nulls. Namely, that its potential for abuse is so high that it shouldn’t even be offered to the programmer as an option.

Exceptions, not even once

In ye olden days, South Park mocked the anti-drug school programs with the compelling arguments of the school guidance councilor Mr. Mackey. It’s a funny reference, but the structure of his speech communicates the error with what I previously believed.

I viewed exceptions as overused, but permissible. After all, we had seen improvement on this front over time. In older versions of .NET, an exception was thrown by web clients for non 200 responses. Really? Is getting an HTTP error code exceptional? Newer versions rightly only throw when something actually exceptional occurs like the underlying connection dropping (though this is arguably still overkill).

Here’s a list of objections to exceptions and my counter arguments at the time.

ObjectionCounter
Exceptions lie because they aren’t in the function
signature.
This can be addressed by “checked exceptions”.
The overhead of the throws is substantial vs an
error code.
Modern computers are really fast. Unless you’re
throwing exceptions in a loop summing millions
of numbers, this will never been a real world
problem.
Inheritance is badIt is, but exceptions don’t have to have inheritance.
You should consider errors at every levelRequiring ? to “rethrow” isn’t accomplishing that!

I actually still believe all these by the way. I just now think exceptions should be eliminated anyway. When I initially started working with languages that didn’t have exceptions, it struck as people being different just to be special little snowflakes. In my defense, this is absolutely a thing with syntax:

  • fn vs func vs function vs nothing
  • var vs let vs foo := 10 (the last one is a classic example of what I call “The Cult of Conciseness”)

My introduction to this concept was in college with Swift. My fellow students did what programmers normally do, they carried over whatever habits and paradigms they had from other languages. For example, requiring explicit types when something can be null is a major improvement. But since people just added safe unwraps everywhere it largely invalidated the purpose. At least the possibility was documented and enforced, but in practice people still just used nulls and null checks everywhere.

I viewed the substitutes for exceptions the same way, though admittedly I wasn’t making a good engagement with the scale of it. This problem was far more pronounced in the null case than the error case. Since people wrote the same bad code, I just viewed it as extra boilerplate.

What I missed

Much like Mr Mackey though, while I was technically correct💺 on paper, in practice this take obviously fell apart. My version of his speech basically went:

So first of all implicit behaviors are bad, you shouldn’t have implicit failures. And uh, treating expected and unexpected failures the same is bad. You shouldn’t do that. Let’s focus our discussion first on exceptions. Exceptions are usually bad and their use has a very distinct code smell, okay? I’m going to pass around a little tiny bit and I want you all to take a smell so you know when someone is improperly using exceptions near you.

Except instead of the marijuana being stolen, my passed around exceptions get widely adopted, duplicated, and used all over the place. Just like with Mackey, this was obviously what was going to happen. It’s not enough to just say something is wrong. If you give people the opportunity to do the wrong thing with limited or no upside, you’ve messed up. This, more than anything else, is why exceptions shouldn’t exist.

The other aspect is that I have come to find that once you engage with trying to do things the right way you learn better habits and write more correct code. Going through the motions, through the boilerplate, actually works on two levels. First, someone engaging with an open mind is confronted with the propagation at every level and will ask if it’s the right design. Second for people who don’t or just don’t know better, the real world isn’t like college. As long as you have people that do it correctly in code review that will hold other accountable, trying to continue writing sloppy code this way won’t work. It just jams up their review.

All rights reserved by the author.