The great advantage of exceptions is that you can deal with problems where you can do womething about them, rather than directly in the function where e.g. a missing file is detected, or in the function's caller, or its caller, &c.
However, exceptions also have to be handled somewhere along the chain. Where these points occur depend on the framework you are using, and what its exception management consists of. The key question is: what are your points of entry where allowing an exception to escape uncaught would have bad effects? Typical examples include
- Event processing code in interactive UI applications (which at least in WinForms and ASP.NET can be caught en masse by providing exception event handlers).
- Integration points where you respond to external messages (e.g. picking up messages from a queue, processing a file, listening on a named pipe, implementing a WCF service).
- Timer events where you do background processing.
- Thread start methods.
Sometimes, you also want to catch a low-level general technical error and rethrow it as a more domain-specific exception. This typically done in well-designed libraries to shield users from its internal implementation details. In an enterprise application, you might want to catch certain SqlExceptions and rethrow them as application-specific exceptions (e.g. YourApp.UnknownCustomer), in order to deal with them at higher levels of logic.
My advice would be: deal with problems at the highest level possible, but ensure that the exception catchers up there have reasonable exceptions to work with. And, by the way, unless you hate your users, don't display the exception and its stack trace to them! ;-)