Log-and-throw is a good pattern iff the entity catching and rethrowing the exception has reason to believe that it contains information which will not get logged further up the call stack--at least not in the most-desired fashion. A couple of reasons this may occur:
- The exception may be caught and rethrown at an application-layer boundary, and may contain privileged information. It would be bad for a database layer to allow an exception saying, e.g. "Attempt to add duplicate key 'fnord' to field 'users'" to reach the outer application layer (which might in turn expose it to a user), but it could be useful for inner portions of the database to throw such an exception and the application interface to catch it, log it securely, and rethrow a somewhat less descriptive exception.
- The exception may be one that the outer layer would likely be expecting to handle without logging, but the inner layer may know something that the outer layer doesn't which would suggest that logging may be useful. As a crude example, a middle application layer might be programmed to try connecting to one server and, if that doesn't work, try another. Flooding the application's log with 'connection failed' messages while a server is down for maintenance might not be helpful, especially since--from the application's perspective, everything worked fine. It may be useful to forward information about the connection failure to a logging resource associated with servers, which could then filter the logs so as to produce a report of when the server went up and down, as opposed to a log of every single connection attempt.