I use Serilog for diagnostics in my .NET Core 5 console application. I can't decide the best logging semantics in conjunction with exception handling. For example, suppose I perform an operation that requires a file to exist. If that file doesn't exist, I throw an exception for flow-control reasons (I need to unwind to properly exit the application). But where and how do I log this? I can think of a few options:
First option - Log before I throw:
if (!File.Exists(myFilePath)) {
_logger.Error("The file does not exist: {File}", myFilePath);
throw new ArgumentException("File does not exist", nameof(myFilePath));
}
Second option - Log the exception when its caught:
try {
if (!File.Exists(myFilePath)) {
throw new ArgumentException("File does not exist", nameof(myFilePath));
}
}
catch (Exception e) {
_logger.Error(e, "An Exception");
}
Code-wise, I like the second option best. As far as the descriptive strings themselves, I'm not repeating myself. However, I feel like the information is going to be communicated in different ways. I am not sure what the output of the second option looks like: Is it going to be structured? It's missing the original log string from the first option.
Which way is best? Are there other options I should be considering?