For exceptions, there are no boundaries between assemblies. An exception operated on a stack, and each stack belongs to a thread.
Please see other answers.
Here is a rule of thumb: in most cases, don't catch exceptions in libraries. You need to catch exceptions on a very top stack frame of each thread.
There are exclusions: sometime you need to catch a raw exception, create a more semantic exception and re-throw it. In rare cases you can block exception propagation completely, as you can fully "fix" the problem during run-time. One such case is wrong user input, and the "fix" would be prompting the user again until the problem is resolved. However, this is not the usual and not the most recommended way. Another case of total blocking of the exception is working with some defected code which is not available in its source form for a patch.
UI has it's own exception handling strategy: catching all exception in the main event-oriented loop. I explain it in one of my past answers. Please see:
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?[
^],
throw . .then ... rethrowing[
^].
—SA