Start here. This is the direct spoken answer to practice first.
Overview
An exception should be caught where code can make a real decision, not automatically at every method in the call chain.
I catch an exception where the current layer can recover, choose an alternative, add meaningful context, or translate it into that layer's contract. A repository can translate a vendor-specific persistence exception into an application data-access failure while preserving the original cause. A web boundary can map a known domain error to an appropriate response. If a method cannot improve the outcome, it should usually let the exception propagate rather than catch and immediately rethrow it.