How can I avoid this pattern? I wish to capture an illegal state, such as found in the contrived example below. Log a structured message followed by throwing an exception containing the same message.
public async Task<int> DoSomeWork(int numerator, int denominator)
{
if (denominator == 0)
{
Logger.LogError("The division : {Numerator}/{Denominator} is invalid as the denominator is equal to zero", numerator, denominator);
throw new ApplicationException($"The division : {numerator}/{denominator} is invalid as the denominator is equal to zero.");
}
//Yes the solution must work with async methods
await Task.Delay(TimeSpan.FromSeconds(1));
//this would have thrown a DivideByZeroException
return (numerator / denominator);
}
I have the above pattern all over my code and it seems crazy, yet I can't find an alternative.
I want the goodness of structured logging, and I also want my Exception messages to align with the log message. Yet I don't want to have to duplicate my error message template strings as seen above.
One approach is to add a custom exception that allows an args collection to be supplied, which can in turn be used with the structured logging. A delegate to the log action can also be added so that whatever handles the exception can call the action supplying an
ILogger
instance.Then in whatever class is handling the exception
and finally your application code