Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exceptions and Abstractions

When should you throw a custom exception?

e.g. I have some code that connects to a server. The code that connects to the server throws an IOException when it fails to connect. In the context of the method it's called, this is fine. It's also fine in the network code.

But as this represents not having a connection (and therefore not working) the exception goes all the way up to the ui. At this stage, an IOException is very ambigous. Something like NoConnectionException would be better.

So, my question is: At what stage should you catch an exception to instead throw another (custom) exception that better fits the abstraction?

like image 904
Macha Avatar asked Sep 06 '25 11:09

Macha


1 Answers

I would expect exceptions to talk in terms of what I've asked the originating method to do. e.g.

read -> ReadException
connect -> ConnectException
buildPortfolio -> FailedToBuildPortfolioException

etc. This abstracts away what's going on under the covers (i.e. are you connecting via sockets etc.). As a general rule, when I create an interface for a component, I often create a corresponding exception or set of exceptions. My interface will be called Component, and my exceptions are usually ComponentException (e.g. RateSource and RateSourceException). It's consistent and easy to export to different projects as a complete component set.

The downside is that you create quite a lot of exceptions, and you may have to perform quite a lot of translations. The upside is that (as you've identified) you get little to no abstraction leakage.

At some point during the hierarchy of method calls (and thus exceptions) you may decide that no recovery can take place (or it's at an inappropriate place) and translate to unchecked exceptions to be handled later.

like image 194
Brian Agnew Avatar answered Sep 08 '25 08:09

Brian Agnew