Вложенная Попытка/Выгода

Имеет вложенная Попытка/Выгода сигнал, что Вы не кодируете чисто? Интересно, потому что в моей выгоде я называю другой метод и если это перестало работать, я получаю другую ошибку периода выполнения, таким образом, я испытываю желание перенести те вызовы в выгоду с другой попыткой/выгодой снова. Интересно, нормально ли это, чтобы сделать это?

например.

    catch (Exception ex)
    {
        transaction.VoidOrder(transactionID);

        LogError(ex.ToString());
        Response.Redirect("Checkout", false);
    }

так VoidOrder или даже LogError методы могли разбомбить. Прямо сейчас, когда я звоню VoidOrder, Я получаю пустой указатель касательно на transactionID потому что это называет метод BL и в том, что метод BL, который я повторно бросаю так, я могу поймать его в этом более высоком уровне в коде выше. Но если я бросаю снова в выгоде затем, я должен поймать это также.

18
задан Phonon 12 May 2011 в 18:53
поделиться

5 ответов

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

Есть способы сократить количество вложенных блоков (например, объединить обработку ошибок с помощью обработчика ASP.NET HttpApplication.Error (также известного как Application_Error )), но вы должны перехватить любые исключения, создаваемые вашим кодом обработки, и реализовать план резервного копирования на случай, если все остальное не удастся.

5
ответ дан 30 November 2019 в 08:48
поделиться

Еще одним решением проблемы вложенности может быть инкапсуляция логики try/catch для внутренних функций (LogError и т.д.) в самих функциях, вместо того чтобы полагаться на то, что вызывающая сторона их перехватит. Для LogError это имеет смысл, потому что вы, вероятно, захотите обрабатывать сломанный регистратор ошибок одинаково, независимо от того, кто пытается зарегистрировать ошибку.

1
ответ дан 30 November 2019 в 08:48
поделиться

Возможно, это вопрос, может ли кто-нибудь понять, почему вы используете вложенные try'ы/catches. Иногда их использование становится неизбежным, но я говорю, что обычно это некрасиво.
Вы должны подумать о том, что разделение задач - это обязательное условие.

Метод getControl не должен вставлять в него скрипт, равно как и метод save не должен делать больше, чем сохранять.

Изучите, что именно должны делать эти методы, и вы получите ответ. Обнуление порядка в случае ошибки выглядит не так уж неудобно. Звучит разумно.

1
ответ дан 30 November 2019 в 08:48
поделиться

Думали ли вы об использовании объекта TransactionScope вместо попытки отката транзакции вручную? Я знаю, что иногда это невозможно, но в большинстве случаев TransactionScope помогал мне. Таким образом, мне не приходилось управлять элементами отката вручную - откаты вручную в любом случае могут быть проблемой, потому что данные находятся в «нестабильном» состоянии, что может испортить всю вашу логику.

0
ответ дан 30 November 2019 в 08:48
поделиться

Вот как мы подходим к проблеме:

Все вызовы с уровня UI/codebehind на другие уровни используют try-catch, где мы всегда ловим пользовательское исключение. Все действия, выполняемые нижележащими уровнями, имеют свои try-catch, которые регистрируют, оборачивают и бросают пользовательское исключение. Пользовательский интерфейс может полагаться на это и искать обработанные исключения с дружественными сообщениями об ошибках.

Codebehind:

protected void btnSubmit_Click(object sender, EventArgs e)
{
    //do something when a button is clicked...
    try
    {
        MyBL.TakeAction()
    }
    catch(MyApplicationCustomException ex)
    {
        //display something to the user, etc.
        ltlErrorPane.Text = ex.Message;

        //or redirect if desired
        if(ex.ErrorType == MyCustomErrorsType.Transactional)
        {
            Response.Redirect("~/Errors/Transaction.aspx");
        }
    }
}

BL:

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

public class MyBL
{
    public static void TakeAction()
    {
        try
        {
            //do something
        }
        catch(SpecificDotNetException ex)
        {
            //log, wrap and throw
            MyExceptionManagement.LogException(ex)
            throw new MyApplicationCustomException(ex, "Some friendly error message", MyCustomErrorsType.Transactional);
        }
        finally
        {
            //clean up...
        }
    }
}

Обработчик исключений:

Собственно обработчик исключений имеет несколько способов регистрации, включая журнал событий, журнал файлов и, наконец, электронную почту, если все остальное не работает. Мы решили просто возвращать false, если регистратор не может выполнить ни одно из ожидаемых действий. IMO это личный выбор. Мы считаем, что вероятность того, что 3 метода не сработают последовательно (журнал событий не сработал, попробуйте файловый журнал, не сработал, попробуйте электронную почту, не сработал), очень мала. В этом случае мы решили разрешить приложению продолжить работу. Другим вариантом было бы позволить приложению полностью завершиться.

public static class MyExceptionManagement
{
    public static bool LogException(Exception ex)
    {
        try
        {
            //try logging to a log source by priority, 
            //if it fails with all sources, return false as a last resort
            //we choose not to let logging issues interfere with user experience

            //if logging worked
            return true;
        }
        catch(Exception ex)
        {
            //in most cases, using try-catch as a true-false is bad practice
            //but when logging an exception causes an exception itself, we do
            //use this as a well-considered choice.
            return false;
        }
    }
}

Наконец, в качестве меры предосторожности мы реализовали обработчик глобального события Application_ErrorGlobal.asax). Это крайняя мера для случаев, когда мы не смогли правильно отловить ошибку. Обычно мы регистрируем и перенаправляем на дружественную страницу ошибки. Если вышеописанная обработка ошибок выполнена успешно, очень немногие ошибки попадут в глобальный обработчик.

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

15
ответ дан 30 November 2019 в 08:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: