I recently had a question about whether a repository should log exceptions that occur during DB updates.
We have a rule that repositories should not call other services. Since a repository call should be the last thing done before data is persisted, there should be no reason to call another service since all business rules and manipulations should already have been applied. The Logger is not a business service, however, and applies no business rules, therefore it should be excluded from this rule.
Another rule we have is that errors should be logged as close to where they happened as possible in order to capture as much of the current context as possible. If an error is found and an exception thrown (without logging) to the caller, the caller must then guess the context and process that resulted in the error. The code that encountered the exception knows exactly what was going on at the time, and so knows best what contextual information will best describe the cause.
Bad incoming parameters is an example of an error that should be logged. On entry to the repository method, incoming parameters should be checked for validity and if they fail, that error should be logged and an exception thrown for the caller to catch.
DB interaction is another thing that should be logged. All DB interactions should be wrapped in a try..catch, and appropriate logic applied depending on the specific exception. A generic repository method call know nothing about the business circumstances that resulted in the attempt to persist the data. Therefore, it should not try to handle exceptions on it’s on, preferring to throw those to the caller. However, the exception should be logged by the repository so pertinent information can also be logged, such as connection timeout and other settings. This contextual info will be unavailable to the caller.
Note that this may result in the same exception being logged multiple times. That’s OK! Each layer will add it’s own contextual info to the log. It should be a rare case that an exception is logged more than 2 or 3 times. Somewhere in that call tree should be something that is prepared to deal with the exception, even if that means aborting the current business transaction.