I don't think this is a discussion which is exclusive to the C++ community, but here are two high-level guidelines which have helped me:
- Throw exceptions only in exceptional circumstances. It sounds obvious, but many APIs get built with exceptions being thrown about 50% of the time they are called (and a boolean return status would have been more appropriate).
- In your catch clauses, know when to consume exceptions, when to rethrow them as-is and when to throw a different type of exception instead. I can't give you a one-size-fits-all rule for this because it's so dependent on your application's needs, but if you take one thing away from this it should be that the silent consumption of an exception might be the worst thing your code could do. Each frame should have some knowledge of what the calling frame(s) expects when things go wrong.