The general philosophy of exceptions, in any language, is that they communicate exceptional circumstances. You should use them accordingly.
If you end up surrounding every function call with a try
block, something is wrong. Exceptions are precisely designed to make error handling logical and not require the programmer to track all possible error paths. Therefore, you should catch exceptions precisely at those points where you can respond meaningfully to them.
If you cannot think of anything better to do than to abort and propagate the error, then there's no point catching an exception. On the other hand, if there are some errors to which you can react sensibly, catch those, and rethrow anything else.
A typical example is if you're processing lots of files. If there's an error anywhere inside the parsing logic, there's nothing you can do, even though parsing may go down many function calls. However, at the main loop you can try
parsing each file, and if there's an exception, you catch that, skip the file and continue with the next one.
If you're writing a library function, you might want to have one final try block surrounding your entire function; that's somewhat up to you, though. Just document cleanly which exceptions the user has to expect from your library.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…