Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should exceptions be planned at the architectural level?

Are there any good resources for planning how exceptions will be used from an architecture perspective? (Or provide your suggestions directly here.) In projects on which I have worked I find that a few common Exceptions are used over and over again and tend to lose their meaning. From: http://jamesjava.blogspot.com/2007/10/exception-plan.html

like image 706
James A. N. Stauffer Avatar asked Sep 17 '08 20:09

James A. N. Stauffer


2 Answers

I half agree with Apocalisp's comment. Instances of Exception should be reserved for cases where a data or processing error has taken place, but can be recovered from by User or System intervention. Instances of RuntimeException should be reserved for those occasions when no intervention within the confines of your application can resolve the issue. These two types are thusly known as Checked and Unchecked exceptions.

An example of Unchecked exceptions would be if a physical resource (such as a database, or a message bus) is unavailable. A RuntimeException is good in this case because you are not planning for the resource to be unavailable, so your business logic doesn't have to constantly check for DatabaseUnavailableException, or something similar. You can handle RuntimeExceptions in a different way (maybe AOP sending an Email) to report the outage and let staff or support fix the physical issue.

Examples of Checked exceptions would be poor data input, or incomplete data access or something which actually fails business logic, but can be checked and recovered from. An example of this might be that a User you searched for is unavailable. It's a separate condition in your business logic that may be checked and handled (say by the View portion of your application which then reports the Exception's message as an error message to the User).

Many frameworks use this model and it seems to work better than I've seen otherwise.

That being said, many do replace checked exceptions with returned nulls, -1, empty String, or Number.MIN_VALUE. While this is okay, if you are not routinely expecting these values from a datasource or method, it should probably represented as an exception.

like image 104
Spencer Kormos Avatar answered Sep 21 '22 13:09

Spencer Kormos


I generally find that obsessing over checked exceptions is overkill. Exceptions should be reserved for unexpected error conditions from which the program cannot reasonably recover. For these, I tend to agree with what you've observed, that special error types tend to lose their meaning.

As a general rule, throw an exception when all of the following are true:

  • The condition can't be recovered from here.
  • The caller can't reasonably be expected to recover from this condition.
  • Somebody will want to debug the situation, so they might want to see the stack trace.

You'll find that if all of those are true, the type of the exception is not important, and you may as well throw java.lang.Error. If any of them are false, then an exception is probably overkill (do you really need the type, message, and stack trace?)

Instead, consider augmenting the return type of methods to indicate expected kinds of failure. For example, use an Option<A> type for methods where it may make sense to return no value in some cases. Use an Either<A,B> type for methods where you might need to return a value whose type depends on failure or success. Where you might have had specialised Exception subtypes before, you can instead just use Either<Fail,A> where Fail is just an enum over the kinds of failures that are expected.

like image 22
Apocalisp Avatar answered Sep 18 '22 13:09

Apocalisp