Вопрос

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

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

    // Error handling code

}
Это было полезно?

Решение

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

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
}

Другие советы

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

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

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

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

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 );
  }
}

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

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

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

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

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

//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
}

Я знаю, что это не тот ответ, который вы ищете, но вообще не комментируйте.Если ваш код недостаточно понятен, чтобы работать сам по себе без комментариев, то вам следует реорганизовать его до тех пор, пока он не станет понятным. Джеффри Пейлерм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;
}

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top