[Eric_Lippert] writes [on his blog](https://ericlippert.com/2008/09/10/vexing-exceptions/) about different types of exceptions: fatal exceptions, boneheaded exceptions, vexing exceptions, exogenous exceptions and how to handle them.
at the core this is about exceptions being used for exceptional circumstances:
* fatal exceptions: can't handle, let crash - important to avoid silent corruption, which is way worse than a crashed program (don't catch)
* boneheaded exceptions: those are bugs in your code and you should fix the code instead of handling the exceptions (don't catch, fix)
* vexing exceptions: are due to poor design decisions - an exception is thrown where it none should have been thrown (use alternatives if possible)
* exogenous exceptions: due to factors outside of your control (always handle)
in my opinion, this is one of _the_ important principles to observe when writing robust code, together with making illegal states unrepresentable.