Richard is pretty much right, the number of exceptions thrown should be appropriate to the task, not a matter of preference.
Exceptions are there to show that something has gone wrong, and it's up to the calling code to decide if it can handle it: if it can, it should - and if it can't it lets "higher level" handle it.
But ... one good way to handle loads of different exceptions in a "simple to handle" way is to nest them:
C++ Tutorial => Nested exception[
^] so that your system throws a single exception (or two) which contains an inner exception that holds the actual source exception.
For example, if you are given a file path and a password and your job is to decrypt the file and return the content, then there are multiple system exceptions plus decryption problems that could be passed up to the caller. But you could embed all of those in an inner exception and pass up a generic "can't decrypt file" exception that is simple to handle, but provides detail if the caller needs to access it.