бросить исключение в блок try, а не в блок catch? - PullRequest
5 голосов
/ 05 августа 2010

Я унаследовал код в нашем проекте, который выглядит следующим образом. Это метод в классе.

protected override bool Load()
{
    DataAccess.SomeEntity record;

    try
    {
        record = _repository.Get(t => t.ID.Equals(ID));

        if (record == null)
        {
            throw new InvalidOperationException("failed to initialize the object.");
        }
        else
        {
            this.ID = record.ID;
            // this.OtherProperty = record.SomeProperty;
            // etc
        } 
    }
    catch (Exception)
    {
        throw;
    }

    return true;
}

Если бы я затем вызвал этот метод Load из своего уровня пользовательского интерфейса, я бы, вероятно, захотел бы иметь блок try-catch для перехвата любого исключения, вызванного неудачей при загрузке экземпляра, например InvalidOperationException, но приведенный выше код кажется мне неправильным.

Не будет ли InvalidOperationException проглочен оператором catch? этот оператор catch также поймает потенциальные проблемы с _repository.Get, а также потенциальные проблемы с настройкой свойств, если запись верна.

Я подумал, что, возможно, мне следует реструктурировать его, добавив больше операторов try catch для обработки операций Get и операций по настройке свойств по отдельности, или добавив больше блоков catch, обрабатывающих различные исключения, но я спросил коллегу, и он предположил, что try catch не имеет значения в этом случае, и должен быть удален полностью, оставляя это как:

protected override bool Load()
{
    DataAccess.SomeEntity record;

    record = _repository.Get(t => t.ID.Equals(ID));

    if (record == null)
    {
        throw new InvalidOperationException("failed to initialize the object.");
    }
    else
    {
        this.ID = record.ID;
        // this.OtherProperty = record.SomeProperty;
        // etc
    } 

    return true;
}

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

Ответы [ 5 ]

6 голосов
/ 05 августа 2010

Когда вы делаете это:

catch (Exception)
{
    throw;
}

Вы, по сути, не обрабатываете исключение.Это, однако, не означает, что вы игнорируете это.Оператор throw распространит исключение вверх по стеку.Ради чистого читаемого кода ваш последний пример намного лучше.

0 голосов
/ 05 августа 2010

Я согласен с вашим коллегой, вы должны ловить только те исключения, которые, как вы знаете, должны быть пойманы. Я обычно пропускаю любые блоки catch, если не знаю точно, зачем мне это нужно в конкретной ситуации. Это потому, что вы склонны скрывать настоящие ошибки в своем коде, если просто помещаете блок try catch вокруг всего. Оставьте обработку ошибок отключенной, пока она вам абсолютно не понадобится - начните с одного глобального обработчика ошибок в самой высокой точке приложения - если это asp.net, вы можете перехватить событие ошибки приложения и регистрировать ошибки там, но моя точка зрения не добавляйте блоки try catch, если вы не знаете, почему их добавление и запись кода, который обрабатывает ошибки, не перехватывает их.

Наслаждайтесь!

0 голосов
/ 05 августа 2010

Исключение будет перехвачено оператором catch, но, поскольку оно имеет оператор throw, оно отбросит исключение. Это имеет тот же эффект, как если бы у вас не было попытки / улова, поэтому ваш коллега прав, предлагая опустить его.

Нет особого смысла добавлять код обработки исключений, если вы фактически не обрабатываете исключение каким-либо образом.

0 голосов
/ 05 августа 2010

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

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

0 голосов
/ 05 августа 2010

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

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