Imagine this simple application use case, say, for fetching data from outisde of the app. These steps represent the "depth" of the layers, from top to bottom.
- UI touch event
- ViewModel handles said event
- Some service / manager reacts accordingly
- The correct request is built and executed
- The object is fetched and returned all the way up.
This is a simple example to make my point, we're not trying to be super-precise here.
What matters is : I'm digging in the layers, and an exception occurs.
The higher I am in the stack, the better I know the context of the error. I know it happened when I hit the "login" button or the "download" button. So I'm thinking I have a lot of information on context.
The deeper I am in the stack, the closer I get to the actual cause of the exception. I know exactly why it happened at this stage. I have a lot of information about the actual error itself. But I don't really want to show it as is to the user (if relevant).
(Note : we're supposing the exception happened at layer 5 or 4 ; the question isn't that relevant if it happens in the UI layer).
As a general rule of thumb, I try to have very specific error messages according to the context rather than the error message itself ; the same exception type could display many different messages depending on where it came from in the UI. I want more precision as I go up the stack.
My question is :
What exception object/design should I use ? I'm confused, should I have very specific exceptions the deeper I get, because I know specific details ? Or on the other hand, should I use very broad exceptions and transform it while it's caught going up the layers, because I understand context better as I move up?
I can't really figure out how I can get both precise/nice messages without having tons of specific exception catching too low in the architecture. Correct me if I'm wrong, but my
Requestshould not have many caught exception types, since the request is not aware of the current context ; yet I need them if I want to be more accurate in my message.
For example, I'll probably use the same
Request class for multiple different calls, so it would be a
RequestException or a
ServerException ; but when the user lives it, he might be doing two very different things.
Again, I'm just making examples up for the sake of the example, but a login and a data-fetching should be handled totally differently, yet, at the bottom, they could be both the same
ServerException, which is way too broad if I want to display something specific to the UI
I'm not sure how to handle this, it seems tricky/confusing, yet it should be very simple since I appear to have all the information I should have. What am I missing?
And more importantly, how do you guys handle your exceptions, usually, when going up the stack?