Подтвердить что ты не робот

Почему resharper говорит, что "Предложение Catch с единственным выражением" throw "избыточно"?

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

Почему resharper говорит, что он избыточен?

try
{
    File.Open("FileNotFound.txt", FileMode.Open);
}
catch
{
    throw;
}
4b9b3361

Ответ 1

Поскольку

try {
    File.Open("FileNotFound.txt", FileMode.Open);
} catch {
    throw;
}

не отличается от

File.Open("FileNotFound.txt", FileMode.Open);

Если вызов File.Open(string, FileMode) завершается с ошибкой, то в любом примере то же самое исключение найдет свой путь до пользовательского интерфейса.

В этом предложении catch вы просто ловите и повторно бросаете исключение, не делая ничего другого, например, регистрируетесь, откатываете транзакцию, обертываете исключение, добавляете к нему дополнительную информацию или что-либо вообще.

Однако

try {
    File.Open("FileNotFound.txt", FileMode.Open);
} catch(Exception ex) {
    GetLogger().LogException(ex);
    throw;
}

не будет содержать избыточности, и ReSharper не должен жаловаться. Аналогично,

try {
    File.Open("FileNotFound.txt", FileMode.Open);
} catch(Exception ex) {
    throw new MyApplicationException(
        "I'm sorry, but your preferences file could not be found.", ex);
}

не будет избыточным.

Ответ 2

Потому что вышеупомянутое утверждение имеет такое же поведение, как если бы его не было. То же, что и запись:

File.Open("FileNotFound.txt", FileMode.Open);

Ответ 3

Потому что код в try уже выбрасывает исключение.

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

Ответ 4

Потому что он избыточен.

Ответ 5

Вы не сделали никакой обработки в блоке catch, просто забросили исключение снова.

Он предупреждает вас, потому что нет смысла в том, что этот try... catch block там.

Кроме того, еще один хороший совет: "throw ex" не сохранит трассировку стека, но "throw" будет.

Ответ 6

Стоит отметить, что пока...

try
{
    DoSomething();
}
catch
{
    throw;
}

... reduntant, следующее не...

try
{
    DoSomething();
}
catch (Exception ex)
{
    // Generally a very bad idea!
    throw ex;
}

Этот второй фрагмент кода был распространен через кодовую базу, которую я унаследовал от нескольких проектов назад, и имеет неприятный эффект, скрывающий исходную трассировку стека исключений. Выброс исключений, которые вы только что поймали таким образом, означает, что вершина трассировки стека находится на уровне throw, без упоминания о DoSomething или каких-либо вложенных вызовах метода, фактически вызвавших исключение.

Удачный код отладки, который делает это!