Является ли неверный пользовательский ввод действительной причиной для исключения? - PullRequest
9 голосов
/ 23 октября 2009

В соответствии с общим справочником .NET Framework: Руководство по устранению ошибок и обработке ошибок исключения не должны создаваться при «нормальных» операциях.Является ли недопустимый ввод данных пользователем в веб-форму, скажем, ввод пользователем повторного имени, нормальным? !!ВАЖНО !!: Я уверен, что у нас почти все есть мнение по этому поводу, пожалуйста, включите ссылку на надежный источник.

РЕДАКТИРОВАТЬ:

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

ДРУГОЕ РЕДАКТИРОВАНИЕ:

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

Ответы [ 9 ]

13 голосов
/ 23 октября 2009

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

6 голосов
/ 23 октября 2009

Недопустимый пользовательский ввод - это ОЖИДАЕМАЯ ситуация. Вы ожидаете, что это произойдет так же часто, как действительный ввод. Когда это так, бросать исключения может быть слишком много.

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

3 голосов
/ 23 октября 2009

Вот как вы это делаете:

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

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


Я согласен с книгой в этом случае. Ваша база данных - это самый низкий уровень вашего приложения, и в ней не должно быть слишком много бизнес-логики (если происходит A, то выполняйте B, если только C, а не D). Это не означает, что вы не можете предоставить полезные методы на уровне данных, которые вы можете использовать, чтобы избежать исключений.

2 голосов
/ 23 октября 2009

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

http://blogs.msdn.com/kcwalina/archive/2005/03/16/396787.aspx http://msdn.microsoft.com/en-us/magazine/dd419661.aspx

1 голос
/ 29 июля 2010

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

int validateUserInfo(struct info)
{
    //...
}

Звонящий будет делать что-то вроде:

int errorCode = validateUserInfo(info);
if (errorCode != 0)
    handleError(errorcode);

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

Теперь кажется, что мне нужно проверить возвращаемые значения и включить в try / catch. Метод validateUserInfo в классе C ++ / C # / Java может генерировать исключение для «исключительной ошибки» и возвращать ошибки проверки «неверные данные» в качестве возвращаемого значения или некоторого другого механизма. Разве это не делает код более сложным из-за какого-то «правила OO»?

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

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

1 голос
/ 23 октября 2009

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

Мы требуем, чтобы наши доменные объекты действовали всегда. Если предпринята попытка создать или передать неверные данные, мы выдаем исключение из объекта домена. В данном случае, однако, это «исключительное обстоятельство». Зачем? Логика в том, что плохие данные никогда не должны попадать в домен. Где-то в этом стеке вызовов находится место, где недопустимые данные можно было ввести в систему - будь то из-за просчета, неверных данных из базового источника данных или из пользовательского ввода.

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

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

1 голос
/ 23 октября 2009

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

0 голосов
/ 23 октября 2009

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

0 голосов
/ 23 октября 2009

Code Complete от Стива Макконнелла содержит контрольный список для защитного программирования, который действительно хорош В тему исключений он включает:

  • Имеются ли в вашем проекте стандарты (все эти козыри)
  • Есть ли альтернативы?
  • Можете ли вы соотнести это внутренне с методом?

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

Конечно, всегда есть смягчающие обстоятельства.

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