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

Блок обработки исключений Microsoft. Разве это не идеальный пример для перестройки?

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

Блок приложений обработки исключений направлен на централизацию и полную настройку с конфигурационными файлами следующих ключевых задач обработки исключений:

  • Регистрация исключения
  • Замена исключения
  • Обтекание исключений
  • Распространение исключения
  • и др.

В библиотеке это делается путем изменения блоков catch try следующим образом:

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}

В зависимости от того, что указано в app.config для имени политики (см. здесь для документов), HandleException будет либо...

  • вывести совершенно новое исключение (заменить исходное исключение)
  • обернуть исходное исключение в новом и выбросить его
  • усвоить исключение (т.е. ничего не делать)
  • Восстановите исходное исключение.

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

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

Например, ваш код, скорее всего, начнет вести себя некорректно, когда вы переконфигурируете так, что конкретное исключение, созданное в определенной точке, теперь проглочено вместо повторного (может быть, код после блока catch, который не должен выполняться, когда исключение имеет место). То же самое касается всех других возможных изменений в обработке исключений (например, replace → rethrow, swallow → wrap).

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

4b9b3361

Ответ 1

Если вы используете исключения для потока управления, тогда вы захотите избегать обработки исключений на основе политик.

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

Например, если вы разрабатываете API, вы можете захотеть, чтобы каждая функция в вашем API выдавала только стандартные исключения (ArgumentException и т.д.), а также ваше собственное исключение для конкретной библиотеки в случае внутреннее нестандартное исключение (например, a MyLibraryException). В этом случае все, что имеет значение, - это то, что что-то не работает правильно. Вы не выбираете исключение и не понимаете, что пошло не так. Вы просто подтверждаете, что что-то пошло не так, и что вы должны что-то сделать сейчас.

Что-то нужно настраивать, потому что на самом деле не важно, что вы делаете. Отображать окно сообщений пользователю? Модальные или немодальные? Записать исключение? Как вы хотите регистрировать исключение? Вызовите веб-службу регистрации? Добавить в файл журнала? Запись в журнал событий Windows? Вставить запись в базу данных? Вставить запись в две базы данных? Это не имеет большого значения для остальной части вашего приложения. Выбор того, как обрабатывать исключение, полностью ортогонален остальной части приложения.

(В качестве стороннего подхода это не то, как я хотел бы подходить к настраиваемой обработке исключений на основе правил. Я бы больше склонялся к стилю AOP, например, регистрировал в контейнере перехватчик исключений-регистраторов.)

Ответ 2

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

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

Ответ 3

Я должен согласиться с утверждением, что "блок обработки исключений решает проблемы, которые на самом деле не существуют". Я использовал блок с момента его выпуска, и я редко чувствую, что на самом деле я получаю много пользы от него. Ну, возможно, немного головной боли. :)

Прежде чем начать, я признаю, что мне нравится функциональность Exception Shielding на границах служб WCF. Тем не менее, это было добавлено сравнительно недавно, не требует кодирования - только атрибуты и конфигурация, а не то, как обычно продается блок. Вот как Microsoft показывает это на http://msdn.microsoft.com/en-us/library/cc309250.aspx

alt text

На мой взгляд, вышесказанное является контролем потока.

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}

Когда вы комбинируете аспект управления потоком с кодом выше, вы определенно не делаете неправильный код выглядящим неправильно. (Не берите в голову, что конструкция if (rethrow) не предлагает много абстракций.) Это может усложнить обслуживание для разработчиков, не знакомых с определениями политики. Если действие postHandlingAction в файле конфигурации изменилось (это, вероятно, произойдет в какой-то момент), вы, вероятно, обнаружите, что приложение ведет себя неожиданным образом, который никогда не тестировался.

Возможно, я бы не счел это нежелательным, если бы блок не обрабатывал управление потоком, а просто позволял вам связывать обработчики вместе.

Но, возможно, нет. Я не помню, чтобы меня когда-либо просили:

  • добавьте новую функциональность при обработке исключения (например, помимо регистрации в журнале событий также отправьте электронное письмо. На самом деле, блок регистрации может сделать это самостоятельно, если вы уже регистрировали исключение самостоятельно. :))
  • изменить поведение обработки исключений (глотать, перебрасывать или создавать новые) во всей "политике".

Я не говорю, что этого не происходит (я уверен, что у кого-то есть история!); Я просто чувствую, что блок приложения обработки исключений усложняет понимание и поддержку программ, и это обычно перевешивает функциональность, предоставляемую блоком.

Ответ 4

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

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

умное программирование, если вы спросите меня...

Ответ 5

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

Ответ 6

На мой взгляд, одно реальное значение использования блока обработки исключений начинается с одной строки кода в вашем блоке catch:

bool rethrow = ExceptionPolicy.HandleException(например, "Политика доступа к данным" );

Одна строка кода - как легко вы можете получить? За одной строкой кода политика, так как она настроена, делает назначение/обновление политики легко выполняемой, без перекомпиляции исходного кода.

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

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