This rule raises an issue on logging calls inside a catch clause that does not pass the raised Exception.
Why is this an issue?
A log entry should contain all the relevant information about the current execution context. The Exception raised in a catch block not only provides the message but also:
- the exception type
- the stack trace
- any inner exceptions
- and more about the cause of the error.
Logging methods provide overloads that
accept an Exception as a parameter and logging
providers persist the Exception in a structured way to facilitate the tracking of system failures. Therefore Exceptions
should be passed to the logger.
The rule covers the following logging frameworks:
- Nuget package - Castle.Core
- Nuget package - Common.Core
- Nuget package - log4net
- Nuget package - NLog
- Nuget package - Microsoft.Extensions.Logging
How to fix it
Code examples
Noncompliant code example
public bool Save()
{
try
{
DoSave();
return true;
}
catch(IOException)
{
logger.LogError("Saving failed."); // Noncompliant: No specifics about the error are logged
return false;
}
}
Compliant solution
public bool Save()
{
try
{
DoSave();
return true;
}
catch(IOException exception)
{
logger.LogError(exception, "Saving failed."); // Compliant: Exception details are logged
return false;
}
}
Resources
Documentation
- Microsoft Learn - Log exceptions
- Microsoft Learn - LoggerExtensions Class
- Microsoft Learn - Logging providers
- Microsoft Learn - The
try-catchstatement - Serilog - Example application
- Serilog Analyzer -
Serilog001: Exception Usage