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

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

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

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

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

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

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

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

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

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

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

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

Ответы [ 6 ]

13 голосов
/ 03 января 2009

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

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

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

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

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

5 голосов
/ 21 января 2010

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

Перед тем как начать, я признаю, что мне нравится функциональность Защита от исключений на границах обслуживания 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 в файле конфигурации изменяется (это, вероятно, произойдет в какой-то момент), вы, вероятно, обнаружите, что приложение ведет себя неожиданным образом, который никогда не тестировался.

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

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

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

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

5 голосов
/ 03 января 2009

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

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

2 голосов
/ 03 января 2009

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

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

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

1 голос
/ 03 января 2009

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

0 голосов
/ 03 января 2009

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

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

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

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

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

...