Где поставить попробовать поймать - PullRequest
19 голосов
/ 07 февраля 2009

Рассмотрим этот сценарий: У меня есть трехслойное приложение, когда пользователь нажимает на кнопку, обработчик события кнопки вызывает метод в бизнес-слое, который делает что угодно с данными, которые предоставляет обработчик события моей кнопки, а затем передает эти данные на уровень доступа к данным, который отправляет их на сервер база данных. Вопрос в том, где поставить попытку поймать? На уровне данных, на уровне бизнеса, на уровне представления или, может быть, обойти их всех? Какова лучшая стратегия для представления обработки исключений, как в этом сценарии?

Ответы [ 11 ]

42 голосов
/ 07 февраля 2009

Мы следуем

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

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

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

6 голосов
/ 07 февраля 2009

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

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

3 голосов
/ 07 февраля 2009

Мантра обработки исключений: «Брось рано, поймай поздно». Вы хотите перехватывать исключения в последний возможный момент, но хотите немедленно их выбросить (не выполняйте большую обработку после определения, что что-то не так, а затем сгенерируйте исключение). Если вы не можете «обработать» исключение, не отлавливайте его.

В большинстве случаев Try ... Наконец, блоки должны встречаться в вашем коде гораздо чаще, чем Try ... Catch.

2 голосов
/ 07 февраля 2009

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

try
{
    //do something 
}
catch(Exception ex)
{
    LogFile.WriteLine(ex.ToString());
    throw;
}  

Примечание: не пишите:

throw ex;

, поскольку это очистит всю полезную информацию стека от исключения.

1 голос
/ 07 февраля 2009

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

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

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

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

Конечно, это всего лишь совет. YMMV. :)

1 голос
/ 07 февраля 2009

Всегда пробуй / лови на верхнем уровне или уровне контроллера.

0 голосов
/ 07 февраля 2009

Вы хотите использовать только команды try catches для управления необработанным кодом. Например, у меня есть COM-объект, с которым я общаюсь, и я не хочу, чтобы он оставался открытым и создавал утечку памяти. Другой приемлемой альтернативой является перехват ошибок в вашей базе данных, прежде чем разрешить продолжение исключения.

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

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

0 голосов
/ 07 февраля 2009

Когда у меня такая многослойная архитектура (а это много), у меня часто будет попытка / уловка на более чем одном слое. Например, try / catch на уровне персистентности, который перехватывает SQLException, выполняет то, что необходимо сделать на уровне персистентности (например, уведомляет администратора), затем выдает новое исключение, которое будет иметь смысл для некоторого кода, который вызывает уровень персистентности , Примером может быть PersistenceException. Следующий уровень не заботится о том, кого следует уведомить о перезапуске базы данных, но он заботится о том, чтобы он не мог сохранить состояние пользователя, поэтому он может перехватить исключение PersistenceException и сообщить пользователю, что его новый номер телефона не был ' хранится в базе данных.

0 голосов
/ 07 февраля 2009

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

0 голосов
/ 07 февраля 2009

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

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