Пользовательское правило FXCop для определения наличия регистрации улова (Анализ пользовательского кода)
Я реализовал несколько "стандартных" правил анализа кода Microsoft. Однако им не хватало одной области, которую они не могли обнаружить в улове, чтобы увидеть, было ли ведение журнала.
Так что мой тестовый проект имеет эти два метода. Я ожидаю, что один из них поднимет мою пользовательскую ошибку, в то время как другой пройдет.
public void CatchTestNoLogging()
{
try
{ string A = "adsf"; }
catch (Exception ex)
{ throw; }
}
public void CatchTestLogging()
{
try
{ string A = "adsf"; }
catch (Exception ex)
{
log.Error("Test Error");
throw;
}
}
Мое пользовательское правило способно определять наличие перехвата, но я не вижу, как определить, используется ли регистрация?
Это SNIP пользовательского правила:
if (iList[i].OpCode == OpCode._Catch)
{
isCatchExists = true; //this gets hit as I want
//so the question is what can I do to detect if logging is implemented in the catch?
}
Просто бы быстрый указатель на то, как я получу доступ, было бы здорово. Благодарю вас
1 ответ
Что ж,
Это не идеально, но вот что я получил. Я знал / имел каркас от Google о том, как искать блок catch... Ну, это половина того, что мне было нужно, поэтому я начал там, и этот код выглядел так:
if (item.OpCode == OpCode._Catch)
{
isCatchExists = true;
}
Поэтому я вошел в отладчик, чтобы посмотреть, как выглядел улов с журналированием (log4net) по сравнению с отсутствием журналирования, и посмотреть, выпадает ли что-то осязаемое. Ну, я нашел это:
Исследуя объект log4net, я вижу это:
Таким образом, я не видел способа определить, что log.error был в перехвате, но я могу определить, есть ли один из них. ТАК я написал это:
public override ProblemCollection Check(Member member)
{
Method method = member as Method;
bool isCatchExists = false;
bool isLogError = false;
if(method != null)
{
//Get all the instrections of the method.
InstructionCollection iList = method.Instructions;
foreach (Instruction item in iList)
{
#region Check For Catch
if (item.OpCode == OpCode._Catch)
{
isCatchExists = true;
}
#endregion
#region Check for Error Logging (log4net)
if (item.Value != null)
{
if (item.OpCode == OpCode.Callvirt && item.Value.ToString() == "log4net.ILog.Error")
{
isLogError = true;
}
}
#endregion
}
if (isCatchExists && !isLogError)
{
Problems.Add(new Problem(this.GetNamedResolution("AddLogging", member.FullName)));
}
}
return this.Problems;
}
Это работает, но с некоторыми оговорками.
Это жестко запрограммировано в log4net. а. Мне не нравится жесткий код, но я все равно добавлю другое правило для других методологий ведения журнала.
Я не могу определить, находится ли log.error в блоке catch. а. Таким образом, у человека может быть log.error в блоке try, и мое правило пропустит его.