The exception re-throw (just "throw" without argument) of very useful, but it is semantic-free. Nothing about business layer and other absurdity. Is it continues propagation of exception
up the stack.
Basically, you need to catch all the exception only on top of each thread, to prevent termination of the application; in all other cases you need to re-throw, just to prevent blocking of exception from propagation. There is a limited number of cases when propagation is blocked (exception is "finally" processed), usually as a work-around of some "bad" third-party code which you cannot improve.
Usually, you only need to re-throw when you add some processing for a specific case but it does not fix the problem completely, so you do only the processing your code is competent about at this point and propagate processing up the stack to leave it to a more general handler. If you don't do this partial processing, you should not catch it. Very typically, you need to catch one type of exception and throw another one.
Usual mistake is not wrong handling an exception but catching it without the purpose. Very typical completely wrong style is catching all exception in some function. Having some code in a separate function is a very bad reason for catching. A rule is: if you don't know what to do with a concrete type of exception, don't catch it. But you always need to catch only on top of the stack of each thread. Catching exception in UI thread is separate, see below.
For further detail, please see my instruction on using exceptions:
How do i make a loop that will stop when a scrollbar reaches the bottom[
^],
When i run an application an exception is caught how to handle this?[
^].
—SA