Why exceptions are still ok
By: Yan Babitski
Tags: Software Design, Error Handling, Refactoring, Programming, Exception Handling

Exceptions are nice. It’s an elegant concept to signal that something went not as planned and handle it separately from the main logic. However, some people claim that exceptions are an anti-pattern and shouldn’t be used, and we’ve looked at the arguments to support that point of view. However, what wasn’t considered is what good things we have when using exceptions: maybe the benefits outweigh the costs?

Arguments against

The previous article lists the following difficulties with exceptions:

Use of exceptions allowed to postpone error handling , and oftentimes with pressure to deliver features it’s not addressed until it is discovered by end-user

, and oftentimes with pressure to deliver features it’s not addressed until it is discovered by end-user Exceptions perform a one-way transfer to another line of code making it not obvious how would execution go just by looking at function code.

making it not obvious how would execution go just by looking at function code. Sometimes exceptions are used instead of return values , which hurts readability and obscures API

, which hurts readability and obscures API Lots of decision have to be made upfront to use exceptions consistently across the project

Essentially there is no question that exceptions are a convenient tool, but there are concerns about the costs of using it in the long run, when most of our time is spent updating existing code, not writing a new one. Let’s walk over each argument and see if there is a good reason to bear with this difficulty.

Postponed error handling

The argument is essentially about the order of things. With exceptions, we can first get the main logic done and then start handling errors (with later possibly skipped because of more important things). With the proposed alternative, StatusOr<T> we would have to propagate the error at least while getting main logic done. It’s trivial so spot an unhandled returned error, and not trivial to spot unhandled exception.

It’s hard to argue that return error forces engineer to at least consider handling the error while with exceptions you might not even know that it could occur. So we could agree that with exceptions more discipline might be required to handle errors. Might be. Because exceptions have a big feature to counter it.

One-way transfer

It could be easy to spot an unhandled returned error, but it’s very easy to not have any unhandled exceptions. We could have some high-level exception handler which logs what the problem is and somehow tells the client of the system that there is a problem. And that is convenient.

And not only convenient, but it is also safe — with returned errors, we still rely on engineers not ignoring returned errors and code reviews to not allow it through if it happens. But if it does happen whole application might crash. Crash might be a good signal that something is very wrong and have to be fixed immediately (“fail fast”, interesting controversial article on the topic), but in this scenario, it’s good to have a choice — if server is handling hundreds of concurrent requests it could be too expensive to fail all of them because of one missed error handling.

Yes, we do sacrifice clarity for it — we might not know that some method throws an exception, but on the other hand, it’s safe to make this mistake — all execution would be interrupted and transferred to this high-level error handler. Well, there are cases where it might not be safe, e.g. if we’re within a transaction and commit an inconsistent state, but such a problem is not specific to exceptions — same could happen with the returned error.