Re: Парадигма работы с исключениями
От: IT Россия linq2db.com
Дата: 12.08.10 14:25
Оценка: 40 (2) +5
Здравствуйте, 0K, Вы писали:

0K>Начал думать над стратегией обработки исключений.

0K>Все исключения возникают по одной из трех причин:

Важно не то по какой причине возникают исключения, а то какая реакция на них возможна, т.к. как их следует обрабатывать. Тогда останется только два варианта: реагируем на исключение или не реагируем. При этом неважно, либо это ошибка пользователя, либо сбой в системе или что-то ещё. По твоей классификации получается, что тип ошибок #1 для твоей программы ожидаем и, соответственно, мы такие ошибки обрабатываем. А системные ошибки вроде закончилось место на диске для твоей программы являются фатальными. Вроде всё правильно. Но, если бы ты писал программу, которая занималась бы, например резервным копированием данных, то всё было бы с точностью до наоборот, ошибки файловой системы обрабатывались бы со всей тщательностью, а реакция на user input (вроде входных параметров) в лучшем случае выдавала бы экран подсказку.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Парадигма работы с исключениями
От: GarryIV  
Дата: 12.08.10 21:04
Оценка:
Здравствуйте, 0K, Вы писали:

0K>

0K>1. Некорректности во внешних данных (внешних сервисов или вводимых пользователем).
0K>Примеры: пользователь ввел вместо числа -- символ.

0K>2. Ошибки в коде программы (кривой код).
0K>Примеры: вышли за границу массива, обратились к защищенной памяти, вызвали из другого потока к потоконебезопасный метод.

0K>3. Ошибки системы.
0K>Примеры: недостаточно памяти, аварийное завершение процесса, переполнен стек, недостаточно места на диске, обрыв соединения, нет связи с базой данных.

0K>4. Ошибки прав доступа. -- под вопросом, не знаю куда отнести


0K>Кстати, ошибки #2 могут породить ошибки #3. И, вроде бы все -- остальные никак не связаны.


Любая ошибка может приводить любой другой.

1 может вызвать
и 2 (хреновая валидация данных и получи деление на ноль)
и 3 (в данных кривой урл вот и нет связи с базой)
и 4 (запросили что-то лишнее)

и так далее и тому подобное.

А вообще такая классификация может быть полезна в рамках оределенного приложения. В рамках другого приложения это все будет ну совсем неуместно.
WBR, Igor Evgrafov
Re[2]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 13.08.10 01:26
Оценка:
Здравствуйте, IT, Вы писали:

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


Это связано. Прямая связь есть.

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

Но нет возможности узнать аппаратное это исключение или нарушение контракта.

IT>Тогда останется только два варианта: реагируем на исключение или не реагируем.


Реагировать можно по разному. Если аппаратное -- просто занесение в лог (попытка).

Если кривой код -- срочное оповещение программиста. Причем он будет на 100% знать, что это кривой код и его проблема, а не проблема, скажем, оборудования клиента или стороннего сервиса.

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

IT>При этом неважно, либо это ошибка пользователя, либо сбой в системе или что-то ещё.


Важно. Еще как важно.

IT>По твоей классификации получается, что тип ошибок #1 для твоей программы ожидаем и, соответственно, мы такие ошибки обрабатываем.


Да. Причем если возникла ошибка данных, значит что-то не так с данными или порядком их обработки.

IT>А системные ошибки вроде закончилось место на диске для твоей программы являются фатальными.


Нет. Я такого не говорил, это вы придумали.

Как поступать с системными ошибками -- решает программа. В 90% случаев она ничего сделать не сможет. Просто занесет в лог. И естественно, Если ошибка системная -- ей лучше закрыться.

Но если программа работает на уровне системы -- она может обработать эту ошибку.
Re[2]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 13.08.10 01:35
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>Любая ошибка может приводить любой другой.


GIV>1 может вызвать

GIV>и 2 (хреновая валидация данных и получи деление на ноль)

Вы не правильно поняли. Ошибки 2 (кривой код) -- могут либо существовать либо нет. В процессе работы программы вы их можете ВЫЯВИТЬ. Но если их нет -- то никакими данными вы их не вызовите.

GIV>и 3 (в данных кривой урл вот и нет связи с базой)


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

GIV>А вообще такая классификация может быть полезна в рамках оределенного приложения. В рамках другого приложения это все будет ну совсем неуместно.


Нет, вы не до конца поняли концепцию. Она полезна для абсолютно всех проектов. Ведь отражает реальную суть вещей, высшая структуризация:

1. Soft
1.1. Code
1.2. Data
1.2.1. Active Data
1.2.1.1. Correct
1.2.1.2. Workflow
1.2.2. Context Data
2. Hard.

Это же не я придумал. Это так компьютер и работа с данными устроена. Просто ошибки должны соответствовать ВЫСШЕЙ СТРУКТУРИЗАЦИИ.
Re[3]: Парадигма работы с исключениями
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.08.10 03:35
Оценка:
Здравствуйте, 0K, Вы писали:

0K>Нет, вы не до конца поняли концепцию. Она полезна для абсолютно всех проектов. Ведь отражает реальную суть вещей, высшая структуризация:


0K>1. Soft

0K> 1.1. Code
0K> 1.2. Data
0K> 1.2.1. Active Data
0K> 1.2.1.1. Correct
0K> 1.2.1.2. Workflow
0K> 1.2.2. Context Data
0K>2. Hard.

0K>Это же не я придумал. Это так компьютер и работа с данными устроена. Просто ошибки должны соответствовать ВЫСШЕЙ СТРУКТУРИЗАЦИИ.


Давай перейдем от теории к практике. Структурируй, плиз, несколько типичных исключений. Например, InvalidOperationException, ArgumentException, наборчик IOException.
Re[3]: Парадигма работы с исключениями
От: andy1618 Россия  
Дата: 13.08.10 06:50
Оценка: 4 (1)
Здравствуйте, 0K, Вы писали:

A>>Ну почему же? В MSDN в рекомендациях по исключениям как раз довольно

A>>внятно прописано, какие классы исключений бывают, и что с ними делать.

0K>Простите, причем здесь "классы исключений"?


Вопрос, как я понимаю, риторическо-провокационный
Посмотрите внимательно на названия стандартных классов исключений:
1) "ArgumentException",
2) "ApplicationException",
3) "SystemException".
А теперь посмотрите на вашу классификацию в исходном посте.
Подозрительная корреляция, не так ли?

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


0K>Речь о том, что у них нет структуризации. И нет четкой парадигмы: какие проблемы к каким исключениям приводят.


Я не против создания чёткой парадигмы. Просто есть подозрение, что это неподъёмная и неблагодарная задача.
Даже сами Майкрософты признали, что их старое мнение о том, что все пользовательские исключения должны наследоваться от "ApplicationException", оказалось ошибочным:

For most applications, derive custom exceptions from the Exception class. It was originally thought that custom exceptions should derive from the ApplicationException class; however in practice this has not been found to add significant value.

Re[4]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 13.08.10 07:00
Оценка:
Здравствуйте, samius, Вы писали:

S>Давай перейдем от теории к практике.


Давай.

S>Структурируй, плиз, несколько типичных исключений.


В такой постановке вопрос неразрешим. Микрософт при разработке архитектуры .Net не удилела должного внимания структуризации типов исключений. Даже статья в MSDN по обработке исключений написана в стиле "не делайте так, не делайте эдак". Напоминает объясления на столбе: "дополнительный доход от 100 у.е. в день (не гербалайф)".

Т.е. там не написано КАК работать с исключениями. А написано лишь как НЕ работать. Ибо они сами не очень то хорошо продумали все нюансы.

S>Например, InvalidOperationException,


По идее это исключение нарушения сценария обработки данных (#1). Но опять-же, часто его применяют не по назрачению: когда пытаетесь приветси тип несовместимому (а это уже кривой код #2).

S>ArgumentException,


Здесь еще хуже. Оно может обозначать как нарушение контракта (кривой код), так и неверные данные. В .Net нет четкой структуризации. Такие разные вещи смешиваются.

S>наборчик IOException.


IOException -- должен быть системным (аппаратным). Но у MS не было четкой структуризации и здесь намешали чего только сами хотели. Может быть и проблема данных (файл не сеществует) и, наверное, проблема кода (?).
Re[5]: Парадигма работы с исключениями
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.08.10 07:05
Оценка:
Здравствуйте, 0K, Вы писали:

S>>ArgumentException,

0K>Здесь еще хуже. Оно может обозначать как нарушение контракта (кривой код), так и неверные данные. В .Net нет четкой структуризации. Такие разные вещи смешиваются.

Это скорее зависит от того как ты воспринимаешь.
Re[5]: Парадигма работы с исключениями
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.08.10 07:27
Оценка:
Здравствуйте, 0K, Вы писали:

0K>Здравствуйте, samius, Вы писали:


S>>Структурируй, плиз, несколько типичных исключений.


0K>Т.е. там не написано КАК работать с исключениями. А написано лишь как НЕ работать. Ибо они сами не очень то хорошо продумали все нюансы.

Это я не буду комментировать.

S>>Например, InvalidOperationException,


0K>По идее это исключение нарушения сценария обработки данных (#1).

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

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

0K>Но опять-же, часто его применяют не по назрачению: когда пытаетесь приветси тип несовместимому (а это уже кривой код #2).

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

S>>ArgumentException,


0K>Здесь еще хуже. Оно может обозначать как нарушение контракта (кривой код), так и неверные данные. В .Net нет четкой структуризации. Такие разные вещи смешиваются.


Типичная проверка предусловий на аргументы. Причем тут дотнет? Так и скажи, что не можешь классифицировать нарушение предусловий в соответствии со своей структуризацией.

S>>наборчик IOException.


0K>IOException -- должен быть системным (аппаратным). Но у MS не было четкой структуризации и здесь намешали чего только сами хотели. Может быть и проблема данных (файл не сеществует) и, наверное, проблема кода (?).


Возьмем конкретный FileNotFoundException. Это проблема кода, данных, или аппаратная?
Возьмем EndOfStreamException. Код, данные, аппаратно?

Забудь про .net и MS. Представь просто ситуацию и классифицируй ее согласно своей структуризации.
Re[6]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 13.08.10 09:09
Оценка:
Здравствуйте, samius, Вы писали:

S>>>Например, InvalidOperationException,


0K>>По идее это исключение нарушения сценария обработки данных (#1).

S>

S>Исключение, которое выдается при вызове метода, недопустимого для текущего состояния объекта.

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

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

В том то и дело: InvalidOperationException применяют где ни попади: и при нарушении контракта, и при нарушении сценария работы.

0K>>Но опять-же, часто его применяют не по назрачению: когда пытаетесь приветси тип несовместимому (а это уже кривой код #2).

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

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

S>>>ArgumentException,


0K>>Здесь еще хуже. Оно может обозначать как нарушение контракта (кривой код), так и неверные данные. В .Net нет четкой структуризации. Такие разные вещи смешиваются.


S>Типичная проверка предусловий на аргументы. Причем тут дотнет?


При том, что в спецификации не продумали правила его применения.

S>Так и скажи, что не можешь классифицировать нарушение предусловий в соответствии со своей структуризацией.


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

S>>>наборчик IOException.


0K>>IOException -- должен быть системным (аппаратным). Но у MS не было четкой структуризации и здесь намешали чего только сами хотели. Может быть и проблема данных (файл не сеществует) и, наверное, проблема кода (?).


S>Возьмем конкретный FileNotFoundException. Это проблема кода, данных, или аппаратная?


Проблема данных.

S>Возьмем EndOfStreamException. Код, данные, аппаратно?


Проблема вызывающего кода.

S>Забудь про .net и MS. Представь просто ситуацию и классифицируй ее согласно своей структуризации.


Объясняю еще раз. Эти исключения сами MS применяют без четкой структуризации. Вы .Net воспринимаете как идеальный продукт богов. Я, имея почти 10 летний опыт программирования, вижу что можно было бы улучшить.
Re[7]: Парадигма работы с исключениями
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.08.10 09:24
Оценка: +1 -1
Здравствуйте, 0K, Вы писали:


0K>Объясняю еще раз. Эти исключения сами MS применяют без четкой структуризации. Вы .Net воспринимаете как идеальный продукт богов. Я, имея почти 10 летний опыт программирования, вижу что можно было бы улучшить.


А я не вижу чем вообще может помочь структуризация. Ты это даже не можешь объяснить. Попытки сделать это с UserFriendlyException привели к тому что ты придумал коды ошибок и текстовые сообщения, что никак не является улучшением.

Если следовать золотому правилу — "не можешь обработать исключение, не лови его", то структуризация и не особо нужна, потому что в каждый момент времени ты будешь перехватывать только конкретные типы. И даже проблемы с InvalidOperationException не возникает, потому что в документации английским по белому написано в каких случаях кидается такое исключение.
Re[7]: Парадигма работы с исключениями
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.08.10 09:33
Оценка:
Здравствуйте, 0K, Вы писали:

0K>Здравствуйте, samius, Вы писали:


S>>>>Например, InvalidOperationException,


0K>>>По идее это исключение нарушения сценария обработки данных (#1).

S>>

S>>Исключение, которое выдается при вызове метода, недопустимого для текущего состояния объекта.

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

0K>Вы смотрите с точки зрения мальчика, который пытается только понять что там придумали дяди. Я смотрю с точки зрения реальности и понимаю, то что они придумали -- имеет слишком много изъянов.


0K>В том то и дело: InvalidOperationException применяют где ни попади: и при нарушении контракта, и при нарушении сценария работы.


Бла-бла-бла. Ситуацию недопустимого состояния объекта ты классифицировать не можешь.

0K>>>Но опять-же, часто его применяют не по назрачению: когда пытаетесь приветси тип несовместимому (а это уже кривой код #2).

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

0K>Ну опять же, вы смотрите с т.з. неопытного мальчика. Ничего само не вылетает: его выбрасывает код, написанный MS. И они так решили.


Код выкидывающий InvalidOperationException при приведении типа, который написан MS, в студию. Иначе ты неопытная девочка.

S>>>>ArgumentException,


0K>>>Здесь еще хуже. Оно может обозначать как нарушение контракта (кривой код), так и неверные данные. В .Net нет четкой структуризации. Такие разные вещи смешиваются.


S>>Типичная проверка предусловий на аргументы. Причем тут дотнет?


0K>При том, что в спецификации не продумали правила его применения.


S>>Так и скажи, что не можешь классифицировать нарушение предусловий в соответствии со своей структуризацией.


0K>А вы не можете разве по моей спецификации? Это контракты. Если возникло такое исключение -- кривой код (вызывавший). Но в .Net это четко не оговорено, по этому если ArgumentException выброшен не из-за кривого кода, а из-за неподходящих данных -- считается нормой.


Типа проверять контракты должен вызывающий код?

S>>>>наборчик IOException.


0K>>>IOException -- должен быть системным (аппаратным). Но у MS не было четкой структуризации и здесь намешали чего только сами хотели. Может быть и проблема данных (файл не сеществует) и, наверное, проблема кода (?).


S>>Возьмем конкретный FileNotFoundException. Это проблема кода, данных, или аппаратная?


0K>Проблема данных.

А не кода, который вместо имени файла подсунул прогноз погоды?

S>>Возьмем EndOfStreamException. Код, данные, аппаратно?


0K>Проблема вызывающего кода.

Ну конечно, контракты на содержимое файла должен проверять вызывающий код
S>>Забудь про .net и MS. Представь просто ситуацию и классифицируй ее согласно своей структуризации.

0K>Объясняю еще раз. Эти исключения сами MS применяют без четкой структуризации. Вы .Net воспринимаете как идеальный продукт богов. Я, имея почти 10 летний опыт программирования, вижу что можно было бы улучшить.


Я бы постыдился с 10-летним опытом настолько "далеко" видеть.
Re[8]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 13.08.10 10:15
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>А я не вижу чем вообще может помочь структуризация. Ты это даже не можешь объяснить. Попытки сделать это с UserFriendlyException привели к тому что ты придумал коды ошибок и текстовые сообщения, что никак не является улучшением.


Коды ошибок Где, простите?

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

G>Если следовать золотому правилу — "не можешь обработать исключение, не лови его",


Вы не поняли идею. Есть информационные исключения. Природа их ясна. Их обработка очень простая -- остановить выполнение операции и отобразить сообщение пользователю.

G>то структуризация и не особо нужна,


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

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

G>потому что в каждый момент времени ты будешь перехватывать только конкретные типы


Как раз таки нет. Почти всегда многие типы нужно обработать совершенно одинаково. Именно по этому существует соблазн написать catch(Exception) (что грозит перехватом и системных исключений).

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


Под неверным состоянием объекта там слишком много понимается. Это слишком общее исключение. Просто сложно было структурировать -- они не стали думать об этом.
Re[8]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 13.08.10 10:36
Оценка:
Здравствуйте, samius, Вы писали:

S>Бла-бла-бла. Ситуацию недопустимого состояния объекта ты классифицировать не можешь.


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

0K>>>>Но опять-же, часто его применяют не по назрачению: когда пытаетесь приветси тип несовместимому (а это уже кривой код #2).

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

0K>>Ну опять же, вы смотрите с т.з. неопытного мальчика. Ничего само не вылетает: его выбрасывает код, написанный MS. И они так решили.


S>Код выкидывающий InvalidOperationException при приведении типа, который написан MS, в студию. Иначе ты неопытная девочка.


int? a = null;
int b = (int)a;

Это упрощенно. Можно более запутывающие примеры с той же идеей.

S>Типа проверять контракты должен вызывающий код?


Да. Именно так. Для того контракты и создаются, дабы вызывающий код ни при каких обстоятельствах (с любыми данными) не мог их нарушить. Если нарушил -- проблема кода.

S>>>Возьмем конкретный FileNotFoundException. Это проблема кода, данных, или аппаратная?


0K>>Проблема данных.


S>А не кода, который вместо имени файла подсунул прогноз погоды?


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

S>>>Возьмем EndOfStreamException. Код, данные, аппаратно?


0K>>Проблема вызывающего кода.


S>Ну конечно, контракты на содержимое файла должен проверять вызывающий код


Нужно знать размер данных в потоке.
Re[9]: Парадигма работы с исключениями
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.08.10 10:52
Оценка:
Здравствуйте, 0K, Вы писали:

0K>Здравствуйте, gandjustas, Вы писали:


G>>А я не вижу чем вообще может помочь структуризация. Ты это даже не можешь объяснить. Попытки сделать это с UserFriendlyException привели к тому что ты придумал коды ошибок и текстовые сообщения, что никак не является улучшением.


0K>Коды ошибок Где, простите?


Я бы предложил в теле исключения сделать Enum и расшифровку.


Остюда
Автор: 0K
Дата: 12.08.10


0K>Я предлагаю текстовые сообщения генерировать в одном месте (в коде, работающем с предметной областью). А вы предлагаете дублирование кода: каждый, использующий библиотеку должен по кодам ошибок (или, еще хуже, по 500 разным типам исключений) самостоятельно писать тексты ошибок, выводимые пользователю.

Ты так и не привел ответ на мой вопрос в той же теме:

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

Здесь
Автор: gandjustas
Дата: 12.08.10


G>>Если следовать золотому правилу — "не можешь обработать исключение, не лови его",


0K>Вы не поняли идею.

Понял

0K>Есть информационные исключения.

Нету таких. Это ты сам придумал.

0K>Природа их ясна. Их обработка очень простая -- остановить выполнение операции и отобразить сообщение пользователю.

Тогда не используй исключения, у них цель другая.


G>>то структуризация и не особо нужна,

0K>Структуризация очень важна. Вы просто не до конца поняли предложенную парадигму.
Это ты придумываешь парадигму, которая вообще говоря насквозь дырявая, а потом пытаешься натянуть её на все исключения.
А структуризация не важна, если следуешь золотому правилу.

0K>Мы можем применять сходные правила ко многим типам исключений. И не рискуем нарваться на проблемы (ака перехват аппаратного исключения).

Еще раз, используй золотое правило, проблем не будет.

G>>потому что в каждый момент времени ты будешь перехватывать только конкретные типы

0K>Как раз таки нет. Почти всегда многие типы нужно обработать совершенно одинаково. Именно по этому существует соблазн написать catch(Exception) (что грозит перехватом и системных исключений).
Это у тебя в голове, я так не пишу и всем сотрудникам запрещаю. А еще FxCop\Code Analisys не дает коммитить такой код.

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

0K>Под неверным состоянием объекта там слишком много понимается. Это слишком общее исключение. Просто сложно было структурировать -- они не стали думать об этом.
А это не имеет значения, имеет значение только то что ты знаешь в конкретном случае. Я знаю что Enumerable.First выкинет InvalidOperationException в случае пустой последовательности, это описано в документации и я буду именно его перехватывать. Мне в этот момент абсолютно все равно на структуризацию.

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

В книге Framework Design Guidelines есть хороший коммент к этому вопросу в разделе ExceptionHandling.
Ты кстати эту книгу читал?
Re[10]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 13.08.10 11:29
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>

G>Я бы предложил в теле исключения сделать Enum и расшифровку.


Enum в теле Exception и коды ошибок вместо Exception -- разные вещи. Если на попытку пополнить телефон вы можете получить 500 однотипных (не немножко разных) ответов, то не имеет смысла создавать 500 разных классов исключений -- достаточно в теле одного сделать Enum с этими вариантами ошибок.

G>Ты так и не привел ответ на мой вопрос в той же теме:


G>

G>Есть два поля ввода телефона на форме, каждый из них одинаково обрабатывается логикой приложения. Где-то в глубине может выпасть исключение, типа "невозможно определить оператора". Как ты сделаешь выбрасывание исключения в данном случае и отображения ошибки пользователю.

G>Здесь
Автор: gandjustas
Дата: 12.08.10


Вы просто мыслите в своих старых концепциях.

Предположим пользователь вводит 2 номера: 1 номер отправителя SMS, второй номер получателя.

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

G>>>Если следовать золотому правилу — "не можешь обработать исключение, не лови его",


G>Понял


Вы подумали что поняли, а на самом деле не поняли.

Текст некоторых исключений должен увидеть пользователь. А каких? Вы знаете?

0K>>Есть информационные исключения.

G>Нету таких. Это ты сам придумал.

Вы правы в том, что на данный момент информационные исключения никак не отличают от контрактных и системных. По этому их как бы и нет. Но это не удобно.

0K>>Природа их ясна. Их обработка очень простая -- остановить выполнение операции и отобразить сообщение пользователю.

G>Тогда не используй исключения, у них цель другая.

А что тогда использовать? Коды ошибок? Строки?

G>Это ты придумываешь парадигму, которая вообще говоря насквозь дырявая, а потом пытаешься натянуть её на все исключения.


То что вы ее не можете понять -- не делает ее дырявой.

G>А это не имеет значения, имеет значение только то что ты знаешь в конкретном случае. Я знаю что Enumerable.First выкинет InvalidOperationException в случае пустой последовательности, это описано в документации и я буду именно его перехватывать. Мне в этот момент абсолютно все равно на структуризацию.


Скажите пожалуйста. Может ли, к примеру, метод GetContentAsInt класса XmlTextReader выбросить InvalidOperationException?

Вот его описание: http://msdn.microsoft.com/ru-ru/library/system.xml.xmlreader.readcontentasint.aspx Согласно документации не может. На самом деле может. Как мне об этом узнать? Является ли это багом?

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

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


Часто важен не сам тип исключения, а его причина.
Re[11]: Парадигма работы с исключениями
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.08.10 12:01
Оценка:
Здравствуйте, 0K, Вы писали:

0K>Здравствуйте, gandjustas, Вы писали:


G>>

G>>Я бы предложил в теле исключения сделать Enum и расшифровку.


0K>Enum в теле Exception и коды ошибок вместо Exception -- разные вещи.

То же самое.

0K>Если на попытку пополнить телефон вы можете получить 500 однотипных (не немножко разных) ответов, то не имеет смысла создавать 500 разных классов исключений -- достаточно в теле одного сделать Enum с этими вариантами ошибок.

А ты только то говорил что InvalidOperationException слишком общий и надо структуризировать




G>>Ты так и не привел ответ на мой вопрос в той же теме:


G>>

G>>Есть два поля ввода телефона на форме, каждый из них одинаково обрабатывается логикой приложения. Где-то в глубине может выпасть исключение, типа "невозможно определить оператора". Как ты сделаешь выбрасывание исключения в данном случае и отображения ошибки пользователю.

G>>Здесь
Автор: gandjustas
Дата: 12.08.10


0K>Вы просто мыслите в своих старых концепциях.

Ты аргументы приводи.

0K>Предположим пользователь вводит 2 номера: 1 номер отправителя SMS, второй номер получателя.


0K>При таком раскладе есть 2 варианта. Если библиотека уже заточена под отправление и знает что номера должно быть 2 -- то она же в UserFriendlyException и должна сообщить какой именно номер не удалось распознать.

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

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

А как ты узнаешь "это поле", если ты выдаешь пользователю ex.Message?

0K>Текст некоторых исключений должен увидеть пользователь. А каких? Вы знаете?

В идеале — никаких.

0K>>>Есть информационные исключения.

G>>Нету таких. Это ты сам придумал.

0K>Вы правы в том, что на данный момент информационные исключения никак не отличают от контрактных и системных. По этому их как бы и нет. Но это не удобно.

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

0K>>>Природа их ясна. Их обработка очень простая -- остановить выполнение операции и отобразить сообщение пользователю.

G>>Тогда не используй исключения, у них цель другая.
0K>А что тогда использовать? Коды ошибок? Строки?
Как уже выяснили выше UserFriendlyException будет выбрасываться не там где действительно появляется исключение, а где-то выше, и единственная цель — передать сообщение. Таким образом совершенно нет необходимости создавать exception, надо ловить что вылетело, и как-то формировать строку по этому делу. Собственно с UserFriendlyException надо делать то же самое.

G>>Это ты придумываешь парадигму, которая вообще говоря насквозь дырявая, а потом пытаешься натянуть её на все исключения.

0K>То что вы ее не можете понять -- не делает ее дырявой.
Да я её прекрасно понимаю, а ты не можешь взглянуть на нее критически.

G>>А это не имеет значения, имеет значение только то что ты знаешь в конкретном случае. Я знаю что Enumerable.First выкинет InvalidOperationException в случае пустой последовательности, это описано в документации и я буду именно его перехватывать. Мне в этот момент абсолютно все равно на структуризацию.

0K>Скажите пожалуйста. Может ли, к примеру, метод GetContentAsInt класса XmlTextReader выбросить InvalidOperationException?

0K>Вот его описание: http://msdn.microsoft.com/ru-ru/library/system.xml.xmlreader.readcontentasint.aspx Согласно документации не может. На самом деле может. Как мне об этом узнать? Является ли это багом?

Читай внимательнее (текст в таблице):

Element
XmlDeclaration
None
Document
DocumentType
Notation
Entity
DocumentFragment

Создается исключение InvalidOperationException.


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

0K>Часто важен не сам тип исключения, а его причина.
И что? Причину всегда можно определить из исключения + документации по конкретному методу.
Re[9]: Парадигма работы с исключениями
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.08.10 12:33
Оценка:
Здравствуйте, 0K, Вы писали:

0K>Здравствуйте, samius, Вы писали:


S>>Бла-бла-бла. Ситуацию недопустимого состояния объекта ты классифицировать не можешь.


0K>Я то могу, да вот вы, похоже, никак не можете понять почему "восьмерки боком пишутся".


Я напомню, что ты смог:

0K>По идее это исключение нарушения сценария обработки данных (#1).


0K>>>Ну опять же, вы смотрите с т.з. неопытного мальчика. Ничего само не вылетает: его выбрасывает код, написанный MS. И они так решили.


S>>Код выкидывающий InvalidOperationException при приведении типа, который написан MS, в студию. Иначе ты неопытная девочка.


0K>int? a = null;

0K>int b = (int)a;

Уел.

S>>Типа проверять контракты должен вызывающий код?


0K>Да. Именно так. Для того контракты и создаются, дабы вызывающий код ни при каких обстоятельствах (с любыми данными) не мог их нарушить. Если нарушил -- проблема кода.


Значит вызывающий код должен проверять соответствие индекса границам массива, наличие ключа в словаре... Отсутствие культуры — тоже проблема вызывающего кода? Что имя файла не начинается на "lpt1:" проверяешь при создании файла?

S>>>>Возьмем конкретный FileNotFoundException. Это проблема кода, данных, или аппаратная?


0K>>>Проблема данных.


S>>А не кода, который вместо имени файла подсунул прогноз погоды?


0K>Проблема кода -- это нарушения контрактов/инвариантов. Если код делает не то, что хотел автор но при этом не нарушает контрактов -- это не проблема кода. Код живет свой жизнью.


Значит то что нет файла с именем "Привет, Зайка, как дела?" — это проблема данных, а не кода, который попутал текст сообщения с именем файла?

S>>>>Возьмем EndOfStreamException. Код, данные, аппаратно?


0K>>>Проблема вызывающего кода.


S>>Ну конечно, контракты на содержимое файла должен проверять вызывающий код


0K>Нужно знать размер данных в потоке.


Данные пожаты и зашифрованы. Вызывающий код не знает ни ключ, ни структуру данных, может даже не знать о чем они.
Re[12]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 13.08.10 12:39
Оценка:
Здравствуйте, gandjustas, Вы писали:

0K>>Enum в теле Exception и коды ошибок вместо Exception -- разные вещи.

G>То же самое.

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

От кодов возврата отказались, т.к. их можно забыть проверить.

А вы что 500 типов исключений в этом случае стали бы писать?

G>А ты только то говорил что InvalidOperationException слишком общий и надо структуризировать


Его могут использовать и при нарушении инвариантов и при неверном сценарии обработки данных. Вот в этом то и проблема -- такие вещи смешивать нельзя.

0K>>Предположим пользователь вводит 2 номера: 1 номер отправителя SMS, второй номер получателя.


0K>>При таком раскладе есть 2 варианта. Если библиотека уже заточена под отправление и знает что номера должно быть 2 -- то она же в UserFriendlyException и должна сообщить какой именно номер не удалось распознать.


G>То есть будет или два метода проверки телефона (что маловероятно)


Зачем 2 метода? Один метод, который может выбросить разные типы UserFriendlyException. Эти Exception нужно обработать и обязательно отобразить пользователю сообщение. Остальные типы Exception (не предназначенные для пользователя) -- полезной информации для пользователя не содержат.

G>, или UserFriendlyException будет выкидываться выше проверки телефона, тогда собственно все выкидывание UserFriendlyException можно (и даже нужно) перенести в слой PL и вообще избавиться там от исключений, а просто выдавать сообщение пользователю.


Наверное создам пример, дабы всем было понятно. А то мы говорим о разных вещах

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

G>А как ты узнаешь "это поле", если ты выдаешь пользователю ex.Message?

UserFriendlyException кроме сообщения пользователю может содержать много полезной информации.

0K>>Текст некоторых исключений должен увидеть пользователь. А каких? Вы знаете?

G>В идеале — никаких.

Ошибаетесь. Нестандартные ситуации в жизни (т.е. в бизнес-процессе, в жизненном процессе) -- так же нужно обрабатывать/отображать с помощью исключений. Это не ошибки в коде -- это ошибки в жизненном процессе.

0K>>Вы правы в том, что на данный момент информационные исключения никак не отличают от контрактных и системных. По этому их как бы и нет. Но это не удобно.

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

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

0K>>>>Природа их ясна. Их обработка очень простая -- остановить выполнение операции и отобразить сообщение пользователю.

G>>>Тогда не используй исключения, у них цель другая.
0K>>А что тогда использовать? Коды ошибок? Строки?
G>Как уже выяснили выше UserFriendlyException будет выбрасываться не там где действительно появляется исключение, а где-то выше, и единственная цель — передать сообщение. Таким образом совершенно нет необходимости создавать exception, надо ловить что вылетело, и как-то формировать строку по этому делу. Собственно с UserFriendlyException надо делать то же самое.

Почему не там? Что-то вы не так поняли.

G>>>А это не имеет значения, имеет значение только то что ты знаешь в конкретном случае. Я знаю что Enumerable.First выкинет InvalidOperationException в случае пустой последовательности, это описано в документации и я буду именно его перехватывать. Мне в этот момент абсолютно все равно на структуризацию.

0K>>Скажите пожалуйста. Может ли, к примеру, метод GetContentAsInt класса XmlTextReader выбросить InvalidOperationException?

0K>>Вот его описание: http://msdn.microsoft.com/ru-ru/library/system.xml.xmlreader.readcontentasint.aspx Согласно документации не может. На самом деле может. Как мне об этом узнать? Является ли это багом?

G>Читай внимательнее (текст в таблице):
G>

G>Element
G>XmlDeclaration
G>None
G>Document
G>DocumentType
G>Notation
G>Entity
G>DocumentFragment

G>Создается исключение InvalidOperationException.


А как я об этом мог узнать из XML-документации? Почему не внесли это исключение в XML-документацию, если по стандарту должны были. Просто в MSDN уже позже дописали.

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

0K>>Часто важен не сам тип исключения, а его причина.
G>И что? Причину всегда можно определить из исключения + документации по конкретному методу.

Да. Можно. Но разные типы исключений могут иметь одну причину. И наоборот: часто один и тот же тип используют для разных причин. А это очень сильно осложняет процесс разработки.
Re[13]: Парадигма работы с исключениями
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.08.10 13:02
Оценка:
Здравствуйте, 0K, Вы писали:

0K>Здравствуйте, gandjustas, Вы писали:


0K>>>Enum в теле Exception и коды ошибок вместо Exception -- разные вещи.

G>>То же самое.

0K>Что то же самое? Вы разницу между исключением и кодом возврата знаете? То что внутри исключения есть номер ошибки -- в этом ничего плохого нет.

Забавная логика. Мы обсуждаем коды ошибок вместо exception. Ты говоришь что одного типа Exception+код ошибки достаточно для всего, я же говорю что это ничуть не лучше тех самых кодов возврата, от которых долго и упорно пытались уйти те кто исключения придумал.

0K>А вы что 500 типов исключений в этом случае стали бы писать?

Я бы вообще в таком случае исключения не использовал.

0K>>>Предположим пользователь вводит 2 номера: 1 номер отправителя SMS, второй номер получателя.


0K>>>При таком раскладе есть 2 варианта. Если библиотека уже заточена под отправление и знает что номера должно быть 2 -- то она же в UserFriendlyException и должна сообщить какой именно номер не удалось распознать.


G>>То есть будет или два метода проверки телефона (что маловероятно)


0K>Зачем 2 метода? Один метод, который может выбросить разные типы UserFriendlyException. Эти Exception нужно обработать и обязательно отобразить пользователю сообщение. Вот в этом и проблема. Один метод проверяет два разных номера, как пользователю узнать к какому номеру относится сообщение? А если номеров 500?


0K>UserFriendlyException кроме сообщения пользователю может содержать много полезной информации.

А все равно название поля не узнает, так как нету у него этой информации, как и кучи другой информации нету.

0K>>>Текст некоторых исключений должен увидеть пользователь. А каких? Вы знаете?

G>>В идеале — никаких.

0K>Ошибаетесь. Нестандартные ситуации в жизни (т.е. в бизнес-процессе, в жизненном процессе) -- так же нужно обрабатывать/отображать с помощью исключений. Это не ошибки в коде -- это ошибки в жизненном процессе.

Обрабатывать — да, отображать — нет.
Ты сам придумал "информационные исключения" и пытаешься что-то всем рассказать, так и не доказав их полезность и применимость. Давай прмиер, там посмотрим.

0K>>>Вы правы в том, что на данный момент информационные исключения никак не отличают от контрактных и системных. По этому их как бы и нет. Но это не удобно.

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

0K>Еще как стоит, если эта информация влияет на ход выполнения программы. Пытаетесь перевести со счета на карту -- исчерпан лимит. Это проблема кода? Нет -- это проблема пользователя и его отношения с банком. Но можно ли продолжать операцию? Нет.

А причем тут исключения?

0K>>>>>Природа их ясна. Их обработка очень простая -- остановить выполнение операции и отобразить сообщение пользователю.

G>>>>Тогда не используй исключения, у них цель другая.
0K>>>А что тогда использовать? Коды ошибок? Строки?
G>>Как уже выяснили выше UserFriendlyException будет выбрасываться не там где действительно появляется исключение, а где-то выше, и единственная цель — передать сообщение. Таким образом совершенно нет необходимости создавать exception, надо ловить что вылетело, и как-то формировать строку по этому делу. Собственно с UserFriendlyException надо делать то же самое.

0K>Почему не там? Что-то вы не так поняли.

Я как раз все так понял, давай пример в коде, я тебе покажу

G>>>>А это не имеет значения, имеет значение только то что ты знаешь в конкретном случае. Я знаю что Enumerable.First выкинет InvalidOperationException в случае пустой последовательности, это описано в документации и я буду именно его перехватывать. Мне в этот момент абсолютно все равно на структуризацию.

0K>>>Скажите пожалуйста. Может ли, к примеру, метод GetContentAsInt класса XmlTextReader выбросить InvalidOperationException?

0K>>>Вот его описание: http://msdn.microsoft.com/ru-ru/library/system.xml.xmlreader.readcontentasint.aspx Согласно документации не может. На самом деле может. Как мне об этом узнать? Является ли это багом?

G>>Читай внимательнее (текст в таблице):
G>>

G>>Element
G>>XmlDeclaration
G>>None
G>>Document
G>>DocumentType
G>>Notation
G>>Entity
G>>DocumentFragment

G>>Создается исключение InvalidOperationException.


0K>А как я об этом мог узнать из XML-документации? Почему не внесли это исключение в XML-документацию, если по стандарту должны были. Просто в MSDN уже позже дописали.

В том то и дело что нет стандарта на xml-документацию.
Обсуждение: http://stackoverflow.com/questions/461306/how-to-document-thrown-exceptions-in-c-net

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

0K>>>Часто важен не сам тип исключения, а его причина.
G>>И что? Причину всегда можно определить из исключения + документации по конкретному методу.

0K>Да. Можно. Но разные типы исключений могут иметь одну причину.

Это как?

0K>И наоборот: часто один и тот же тип используют для разных причин. А это очень сильно осложняет процесс разработки.

Пример? Чтобы один метод кидал одно и то же исключение по разным причинам.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.