Item Number 6 in this article states:
Try not to re-throw the exception because of the price. Bu if re-throwing had been a must, re-throw the same exception instead of creating a new exception. This will bring additional performance. You may add additional info in each layer to that exception.
Well but this violates the separation of layers, isn't it?
Let's say I have a specific implementation of DAO which throws an SQLException
Let's say my Service Layer (or Business Layer..) calls a method from the DAO Layer, but decides not to handle the Exception thrown.
If I re-throw the SQLException to the View Layer, my View Layer will not only be coupled to the DAO Layer, isn't it?
Isn't it right to throw a new Exception, so that View is dependent only on layer one level below, and not two?
What advantages does throwing the same Exception bring, except performance?
When an exception occurred, if you don't handle it, the program terminates abruptly and the code past the line that caused the exception will not get executed.
Java does not allow us to catch the exception twice, so we got compile-rime error at //1 .
Throwing a new Exception blows away the current stack trace. throw; will retain the original stack trace and is almost always more useful. The exception to that rule is when you want to wrap the Exception in a custom Exception of your own.
When an exception is thrown the method stops execution right after the "throw" statement. Any statements following the "throw" statement are not executed.
If I re-throw the
SQLException
to the View Layer, my View Layer will not only be coupled to the DAO Layer, isn't it?
This is absolutely correct.
Isn't it right to throw a new Exception, so that View is dependent only on layer one level below, and not two?
Absolutely. If your DAO layer cannot handle the exception coming from SQL, it should catch it, make as much sense of it as possible, and throw its own exception.
Consider an example: let's say your DAO layer allows you to add new items where a certain attribute must be unique. SQL layer may have a unique constraint or a unique index to enforce this constraint on RDBMS layer. If the caller of your DAO layer attempt saving an object that violates the uniqueness constraint, SQL exception would be thrown. If you let this exception propagate to callers, chances are that they would have no idea of what to do with it, and perhaps even show it to end-users:
ORA-00001: unique constraint (UxPatient_rec_soc) violated
This solution is very bad, but an alternative to try and make sense of it on the client is even more fragile.
Your DAO should catch the exception, decide what it means for the caller, and throw its own exception. This way you would be able to change your implementation independently of your caller.
General note: Performance considerations should be among the least important when deciding on throwing / re-throwing an exception, because exceptions should be thrown only in rare exceptional situations. Clarity of your interfaces is a lot more important.
I agree with you on that throwing a more descriptive exception towards your layer wrapping the original one would be more convenient. The SQLException in this case might be a low-level issue which can be interpreted and put into business context by throwing a new more descriptive exception.
Also please consider that usually the performance of error handling itself is not something you'd like to optimize for. So it's true that throwing an exception is slower compared to returning from the method, but this happens only when something goes wrong. (Because you should avoid using exceptions for handling normal program flows)
I don't see any advantage in throwing the same exception, unless you really can't add any information by wrapping it. In that case don't do that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With