In addition to the Solution 1:
One ultimate requirement to handling exceptions: catch them all on the top stack frame of each thread. Event-oriented UI threads have their own twist: all exceptions should be caught in the main even cycle of the thread. Usually, UI libraries have the special event invoked when such exception caught.
It does not mean that exceptions may not be caught in other places. Sometimes it is unavoidable, but the idea is to catch as little as possible. Main feature of exception handling is the isolation from the "regular" code. The over-catching is much more usual mistake then not catching. I call the places where the exceptions are handled the "points of competence". Read the Ron's answer to understand what it means.
One of the worse problem is catching the exception without doing anything (fixing a problem of re-throwing), which blocks further exception propagation. This is one of the worse mistakes, but there are rare cases where it is needed. This is sometimes should be done to compensate some defects in bad software libraries which don't have source code accessible for patching their problems.
[EDIT]
On the nature and main idea of exceptions, please see my past answer:
Does Exception in C# Constructor Cause Caller Assignment to Fail?[
^].
—SA