In my experience, why
an exception was thrown is rarely as important as that
it was thrown.
I.e. the calling code is almost never interested in why something didn't work out, it only needs to log that it couldn't complete it's own task, and the reason for it (so that you can see afterwards what went wrong). There is very seldom any active attempt to actually recover from the error in a very specific way, apart from perhaps waiting, doing it again etc.
Disambiguating different reasons for the error and adjusting to that is better handled at a lower level of the code, closer to where the error occurred, and there you already have the proper granularity, i.e. that an exception occurred.