Комментируя попробуем catch catch - PullRequest
4 голосов
/ 05 января 2009

Как правильно объяснить обработку ошибок в операторе try-catch? Кажется, что вы могли бы поместить пояснительные комментарии в начале блока try или в блоке catch.

// Possible comment location 1
try
{   
    // real code
}
// Possible comment location 2
catch
{
    // Possible comment location 3

    // Error handling code

}

Ответы [ 8 ]

17 голосов
/ 05 января 2009

Я обычно делаю следующее. Если обрабатывается только одно исключение, я обычно не беспокоюсь, так как оно должно быть самодокументированным.

try
{   
    real code // throws SomeException
    real code // throws SomeOtherException
}
catch(SomeException se)
{
    // explain your error handling choice if it's not obvious
}
catch(SomeOtherException soe)
{
    // explain your error handling choice if it's not obvious
}
10 голосов
/ 05 января 2009

«Комментарий - ложь» . Работайте с этими именами переменных и общей логикой, чтобы вы могли избежать этого. И если вам действительно нужно лгать, делайте это внутри блока catch.

5 голосов
/ 05 января 2009

Я не думаю, что это вообще имеет значение.

Я думаю, что важно помнить при комментировании адрес , почему код такой, какой он есть, а не , что делает код, в первую очередь. Это не значит, что вы не должны объяснять сложную логику в кратком комментарии, но почему это гораздо важнее.

4 голосов
/ 05 января 2009

Как насчет простой настройки кода, чтобы он не нуждался в дополнительных комментариях?

try
{ 
   performDifficultAct( parameter );
}
catch (ArgumentOutOfRangeException couldNotFindArgument)
{
   // handle exception
}
catch (Exception otherUnknownException )
{
   // handle exception
}

Нет необходимости документировать, если вы можете использовать свою переменную и метод именования, чтобы показать, что происходит. Нет необходимости документировать, если вам приходится регистрировать или вызывать исключения - сообщение о регистрации в исходном коде должно быть самоочевидным в любом случае. Единственный раз, когда вам понадобится дополнительная документация в вашем коде, это когда совершенно неочевидно, что делает код, или это простой промах или неоднозначный шаг, который вы должны добавить, который потребует объяснения для любого, кто смотрит на код в будущем.

Редактировать: Чтобы прояснить немного, вот немного больше о том, как я мог бы использовать эти операторы "catch" для предоставления полезной информации как программисту по обслуживанию, так и пользователям / support / QA / всем, кто использует программное обеспечение. Также иллюстрация ситуации, когда я абсолютно хотел бы добавить дополнительные комментарии в коде:

public void PerformSomeActionOrOther(string parameter)
{
  try
  { 
     // For some reason an eleven character string causes a bluescreen from Kernel32
     if (parameter.Length==11) parameter+=" ";

     performDifficultAct( parameter );
  }
  catch (ArgumentOutOfRangeException couldNotFindArgument)
  {
     this.Log.WriteLn("Argument out of range exception in ArbitraryClass.PerformSomeActionOrOther");
     this.Log.WriteLn(String.Format("Probable cause is that {0} is not in the array", parameter));
     this.Log.WriteLn(String.Format("Exception: {0}", couldNotFindArgument.Message));
  }
  catch (Exception otherUnknownException )
  {
     this.Log.WriteLn("Unexpected exception in ArbitraryClass.PerformSomeActionOrOther");
     this.Log.WriteLn(String.Format("Exception: {0}", otherUnknownException.Message));
     throw( otherUnknownException );
  }
}
2 голосов
/ 05 января 2009

Определенно не комментируйте верхнюю часть этого, потому что, что вы можете с пользой сказать, кроме «запуска блока обработки исключений здесь»? Комментарии к заявлениям о улове лучше, но в целом, что вы еще скажете? "Обрабатывать исключение NullPointerException"?

Я бы пошел за комментарием. Если вам нужно сказать, что вы делаете что-то захватывающее, например, цепочку к исключению из домена приложения.

1 голос
/ 05 января 2009

Местоположение не имеет значения, если вы последовательны. Мои личные предпочтения таковы:

//comment 1: code does XYZ, can cause exceptions A, B, C
try {
    //do something
}
//comment 2: exception A occurs when foo != bar
catch (ExceptionA a) {
    //do something
}
//comment 3: exception B occurs when bar is null
catch (ExceptionB b) {
    //do something
}
//comment 4: exception B occurs when foo is null
catch (ExceptionC c) {
    //do something
}
1 голос
/ 05 января 2009

Я думаю, что хорошо написанный try / catch должен быть лаконичным и конкретным. Я согласен с @Jason в том, что , почему важнее, но в равной степени важно держать код внутри catch как можно более кратким.

Было бы также полезно, если бы вы использовали определенные исключения для перехвата. Например, если вы используете Java, попробуйте перехватить исключение NullPointerException, а не универсальное исключение. Это должно объяснить, почему существует попытка перехвата и что вы делаете для ее устранения.

0 голосов
/ 19 января 2009

Я знаю, что это не тот ответ, который вы ищете, но не комментируйте вообще. Если ваш код недостаточно ясен, чтобы его можно было оставить без комментариев, вам следует рефакторинг до тех пор, пока он не станет. Джеффри Палерм o только что написал сообщение в блоге , в котором говорится лучше всего.

Как правило, комментарии имеют тенденцию документироваться либо:

  • Код слишком компактный. Вещи, которые выглядят так: ++i?--g:h-i;
  • Длинные блоки кода, которые необходимо суммировать
  • Код, который является одноразовым или не имеет четкой причины для существования

См. Ниже упрощенный пример некоторых простых комментариев к вашему блоку исключений и версию, которая устраняет необходимость в комментариях.

bool retries = 0;
while (retries < MAX_RETRIES)
{
    try
    {
        ... database access code
        break;
    }
    // If under max retries, log and increment, otherwise rethrow
    catch (SqlException e)
    {
        logger.LogWarning(e);
        if (++retries >= MAX_RETRIES)
        {
            throw new MaxRetriesException(MAX_RETRIES, e);
        }
    }
    // Can't retry.  Log error and rethrow.
    catch (ApplicationException e)
    {
        logger.LogError(e);
        throw;
    }
}

Хотя приведенные выше комментарии способствуют возможности повторного использования, вам, по сути, необходимо поддерживать как код, так и комментарии. Это возможно (и предпочтительно) реорганизовать, чтобы оно было понятнее без комментариев.

bool retries = 0;
while (canRetry(retries))
{
    try
    {
        ... database access code
        break;
    }
    catch (SqlException e)
    {
        logger.LogWarning(e);
        retries = incrementRetriesOrThrowIfMaxReached(retries, e);
    }
    catch (ApplicationException e)
    {
        logger.LogError(e);
        throw;
    }
}

...

private void incrementRetriesOrThrowIfMaxReached(int retries, Exception e)
{
    if (++retries >= MAX_RETRIES)
        throw new MaxRetriesException(MAX_RETRIES, e);

    return retries;
}

private bool canRetry(int retries)
{
    return retries < MAX_RETRIES;
}

Последний пример может показаться большим количеством кода для очень тонкой выгоды, но выгоды невозможно переоценить. Код также понятен, но у вас есть то преимущество, что вам не нужно иметь отдельный набор метаданных (комментариев) для объяснения кода. Код объясняет сам. Если ваш блок кода перехвата слишком длинный и нуждается в комментариях для подведения итогов, подумайте о рефакторинге его в отдельный метод, чтобы улучшить читабельность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...