Пользовательское правило 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;
 }

Это работает, но с некоторыми оговорками.

  1. Это жестко запрограммировано в log4net. а. Мне не нравится жесткий код, но я все равно добавлю другое правило для других методологий ведения журнала.

  2. Я не могу определить, находится ли log.error в блоке catch. а. Таким образом, у человека может быть log.error в блоке try, и мое правило пропустит его.

Другие вопросы по тегам