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

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

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

  • Регистрация исключения
  • Замена исключения
  • Упаковка исключения
  • Распространение исключения
  • и т.п.

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

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).

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

6 ответов

Решение

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

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

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

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

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

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

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

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

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

http://i.msdn.microsoft.com/Cc309250.05-CrossLayer(en-us,MSDN.10).gif

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам