Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 12.08.10 01:29
Оценка:
Начал думать над стратегией обработки исключений.

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

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

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

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

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


Это очень важно. Хотя в .Net (и не только) на причину внимания не обращают.

По идее должно быть 3 базовых класса для всех исключений. Программист смог бы генерировать только исключения "некорректности данных". Системные исключения генерируются Операционной Системой. А исключения "кривого кода" средой исполнения.

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

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

Что вы думаете о такой структуризации? И куда отнести ошибки прав доступа? Какие еще есть типы ошибок, которые не вписываются в данную парадигму?
Re: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 12.08.10 01:43
Оценка:
Здравствуйте, 0K, Вы писали:

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


Еще добавлю

0K>3. Ошибки системы.


Ошибки системы обязательно связаны с физическим устройством: процессором, диском, ОЗУ, сетевой картой и пр. Лишь в редких исключениях мы можем что-то с ними сделать (повторить попытку или переконфигурировать устройство).

4. Ошибки прав доступа.

Сначала хотел отнести к системным. И действительно, иногда физическое устройство определяет кто имеет к нему доступ а кто нет. Но с другой стороны ошибки доступа можно рассматривать как ошибки данных (т.е. реакция на наверно введенный пароль, скажем так). В общем -- пока не знаю. Пусть будут особняком.
Re: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 12.08.10 01:47
Оценка:
Здравствуйте, 0K, Вы писали:

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


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

Получается 5-ть причин возникновения ошибок.
Re: Парадигма работы с исключениями
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 12.08.10 02:00
Оценка: 4 (1)
Здравствуйте, 0K, Вы писали:

0K>По идее должно быть 3 базовых класса для всех исключений. Программист смог бы генерировать только исключения "некорректности данных". Системные исключения генерируются Операционной Системой. А исключения "кривого кода" средой исполнения.


Я вот много работаю с DirectX (DirectShow), там куча COM объектов, и все методы могут вернуть код ошибки. И ошибки обычно возвращаются, когда нет нужной версии DirectX'a, когда нет нужного кодека, когда наоборот влез чужой кодек и не дает правильно соединиться, когда нарушен порядок совершения некоторых действий и т.д. Т.е. это далеко не всегда ошибки логики моей программы — они зависят от состояния системы и third-party компонентов, но не зависят от конкретных устройств вроде диска и сети. Что с ними прикажешь делать?
Re[2]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 12.08.10 02:34
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Я вот много работаю с DirectX (DirectShow), там куча COM объектов, и все методы могут вернуть код ошибки. И ошибки обычно возвращаются, когда нет нужной версии DirectX'a, когда нет нужного кодека,


Вы вводите данные в проблемную систему (где возникает исключительная ситуация). Среди этих данных, есть номер нужного кодека или нужной версии DirectX. Система честно отвечает, что не в состоянии обработать эти данные. Т.е. проблема в данных. Вам нужно использовать другую систему, которая эти данные сможет обработать (новую версию).

DM>когда наоборот влез чужой кодек и не дает правильно соединиться,


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

DM>когда нарушен порядок совершения некоторых действий и т.д. Т.е. это далеко не всегда ошибки логики моей программы — они зависят от состояния системы и third-party компонентов, но не зависят от конкретных устройств вроде диска и сети. Что с ними прикажешь делать?


А это выше я добавил: нарушения сценария работы.

Сейчас еще немного подумал. Структурировать можно так:

1.1. Ошибка активных данных: а) корректность данных; б) сценарий обработки данных.
1.2. Ошибка контекстных данных (права доступа).

2. Ошибка в коде (нужно выразить более точно).

3. Ошибка оборудования или системы.
Re: Парадигма работы с исключениями
От: samius Япония http://sams-tricks.blogspot.com
Дата: 12.08.10 03:45
Оценка:
Здравствуйте, 0K, Вы писали:

0K>По идее должно быть 3 базовых класса для всех исключений. Программист смог бы генерировать только исключения "некорректности данных". Системные исключения генерируются Операционной Системой. А исключения "кривого кода" средой исполнения.

Что же делать программисту, если данные корректны, а код не может их обработать? Откуда об этом узнает среда исполнения?

0K>Тогда бы все было намного яснее. Если возникло исключени #3 (системное) -- то как правило с ним ничего сделать нельзя -- только показать пользователю, отобразить информацию. Если исключение #2 (кривой код) -- то программист должен исправить ошибку в своей программе. Ну и если #1 -- неверные данные -- то либо пользователь должнен вводить данные правильно (для пользователя эти исключения нужно обрамлять в красивые сообщения об ошибках) либо сообщить в тех. поддержку сервиса, что они выдают ошибочные данные (либо перестроить логику обработки этих данных).


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


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

0K>Что вы думаете о такой структуризации? И куда отнести ошибки прав доступа? Какие еще есть типы ошибок, которые не вписываются в данную парадигму?
Re[2]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 12.08.10 03:49
Оценка:
Здравствуйте, samius, Вы писали:

S>Что же делать программисту, если данные корректны, а код не может их обработать? Откуда об этом узнает среда исполнения?


Что значит "не может обработать"? Выдает исключение о некорректности данных? Значит для программы данные являются некорректными. Возможно другая программа сможет их обработать (или новая версия этой программы).

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


Ошибки в данных не могут привести к ошибкам соглашений. Они могут лишь ВЫЯВИТЬ, что код был кривым. Историю про старика с бородой и одеялом знаете?
Re: Парадигма работы с исключениями
От: andy1618 Россия  
Дата: 12.08.10 04:03
Оценка:
Здравствуйте, 0K, Вы писали:

0K>Это очень важно. Хотя в .Net (и не только) на причину внимания не обращают.


Ну почему же? В MSDN в рекомендациях по исключениям как раз довольно
внятно прописано, какие классы исключений бывают, и что с ними делать.
Re[3]: Парадигма работы с исключениями
От: samius Япония http://sams-tricks.blogspot.com
Дата: 12.08.10 04:10
Оценка:
Здравствуйте, 0K, Вы писали:

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


S>>Что же делать программисту, если данные корректны, а код не может их обработать? Откуда об этом узнает среда исполнения?


0K>Что значит "не может обработать"? Выдает исключение о некорректности данных? Значит для программы данные являются некорректными. Возможно другая программа сможет их обработать (или новая версия этой программы).


Допустим я написал программу чтения doc-ов. Открываю файл. Файл корректный с точки зрения MSOffice, а моя программа его прочитать не может, потому как не смогла. Данные корректны, а программа — нет.

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


0K>Ошибки в данных не могут привести к ошибкам соглашений. Они могут лишь ВЫЯВИТЬ, что код был кривым. Историю про старика с бородой и одеялом знаете?


Так откуда система узнает о том что код кривой?
Нет, не знаю.
Re: Парадигма работы с исключениями
От: git  
Дата: 12.08.10 04:57
Оценка: 8 (1)
Здравствуйте, 0K, Вы писали:

0K>2. Ошибки в коде программы (кривой код).

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

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

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

Но мне кажется эта "классификация" не имеет прямого отношения к обработке исключений.
По непосредственно обработке придерживаюсь следующих (очевидных?) правил:
1. Все исключения должны логироваться + как можно больше данных приведших к ним. Т.е. если была ошибка в базе данных то не плохо было бы видеть сам "плохой" запрос, данные по результатам которых он был сформирован и (на сервере) исходный входящий запрос. При тестировании можно, грубо говоря, запускать батник и проверять что до запуска приложения и после остановки лог пустой, очистка лога на совести человека.

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

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

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

Вроде ничего не забыл. При таком раскладе, опять же имхо, то как именно организована иерархия исключений, не так принципиально — в любом случае надо смотреть на контекст и попытаться отобразить наиболее важную информацию. Опять же если исключение совсем нигде не было предусмотрено, то в любом случае ничего кроме мессадж бокса с текстом в исключении не покажешь и немного наивно в такой ситуации решать что делать дальше исходя исключительно из базового класса.
Re: Парадигма работы с исключениями
От: Qbit86 Кипр
Дата: 12.08.10 05:20
Оценка: 4 (1)
Здравствуйте, 0K, Вы писали:

0K>Что вы думаете о такой структуризации? И куда отнести ошибки прав доступа? Какие еще есть типы ошибок, которые не вписываются в данную парадигму?


У меня другая струтуризация.

1) Logic Exceptions. То, что порождается ассертами, проверка инвариантов. Типа, «Мамой клянусь, в этом состоянии эта переменная должна быть чётной по построению!» Этот тип исключений не обрабатывается в catch-блоке; реакция на этот тип исключений заключается в баг-репорте автору библиотеки.

2) Usage Exception. Порождается при невыполнении контрактов того или иного метода со стороны вызывающего кода. Скажем, метод библиотеки умеет работать только с непустыми строками, и поэтому бросает ArgumentException, если параметр String.IsNullOrWhitespace. Это не проверка правильности аргументов, это проверка того, что правильность аргументов была проверена вызывающим кодом. Этот тип исключений не обрабатывается в catch-блоке; реакция на этот тип исключений заключается в предварительной проверке в пользовательском коде перед вызовом метода выполнения предусловий. Желательно, чтобы текст сообщений состоял из двух предложений: «Что произошло. Как исправить вызывающий код, чтобы исключение не выбрасывалось.»

3) Runtime Exception (название, быть может, не самое удачное). Исключения, которых нельзя избежать в дизайн-тайме. Скажем, FileNotFoundException: ты не можешь проверкой существования файла перед вызовом метода гарантировать, что этот файл будет существовать в следующий момент времени. Именно этот тип исключений обрабатывается в catch-блоке: оборачивается, заменяется, пробрасывается, останавливается.

4) System Failures. Часто, единственной реакцией является FastFail. Скажем, при OutOfMemoryException поздно пить боржоми, возможности обработать исключение может и не быть. Этот тип исключений, имхо, должен пробрасываться до самого внешнего кода.
Глаза у меня добрые, но рубашка — смирительная!
Re[2]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 12.08.10 05:23
Оценка:
Здравствуйте, andy1618, Вы писали:

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

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

Простите, причем здесь "классы исключений"? Речь о том, что у них нет структуризации. И нет четкой парадигмы: какие проблемы к каким исключениям приводят.
Re[4]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 12.08.10 05:34
Оценка:
Здравствуйте, samius, Вы писали:

S>Допустим я написал программу чтения doc-ов. Открываю файл. Файл корректный с точки зрения MSOffice, а моя программа его прочитать не может, потому как не смогла. Данные корректны, а программа — нет.


Программа при этом выбросит исключение? Или просто утеряет часть/все данные?

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

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

S>Так откуда система узнает о том что код кривой?


Ниже человек хорошо объяснил: нарушение контракта (метод вызывается с неверными параметрами) и нарушение инварианта (на каком-то этапе работы стало понятно, что состояние объекта испорчено).
Re[5]: Парадигма работы с исключениями
От: samius Япония http://sams-tricks.blogspot.com
Дата: 12.08.10 05:46
Оценка:
Здравствуйте, 0K, Вы писали:

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


S>>Допустим я написал программу чтения doc-ов. Открываю файл. Файл корректный с точки зрения MSOffice, а моя программа его прочитать не может, потому как не смогла. Данные корректны, а программа — нет.


0K>Программа при этом выбросит исключение? Или просто утеряет часть/все данные?


Хорошо бы чтобы программа сказала что я не могу прочитать эти данные, а не о том что данные не корректны для неё.

0K>В идеале ваша программа должна выбросить исключение наследуемое от "некорректные данные". Не важно что для MSOffice или для новой версии MSOffice эти данные корректны. Для вашей программы они не корректны и точка. Вот сделаете новую версию -- данные будут корректны и для нее.


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

S>>Так откуда система узнает о том что код кривой?


0K>Ниже человек хорошо объяснил: нарушение контракта (метод вызывается с неверными параметрами) и нарушение инварианта (на каком-то этапе работы стало понятно, что состояние объекта испорчено).


Как система узнает что состояние объекта испорчено-то?
Re[2]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 12.08.10 05:46
Оценка:
Здравствуйте, git, Вы писали:

git>Наверное эти ошибки можно разделить на нарушение контракта (метод вызывается с неверными параметрами) и нарушение инварианта (на каком-то этапе работы стало понятно, что состояние объекта испорчено).


Спасибо за подсказку. Попытку записи в защищенную память отнести к нарушению инварианта? Или попытку привести объект к несовместимому типу?

git>Но мне кажется эта "классификация" не имеет прямого отношения к обработке исключений.


Еще как имеет. Дело в том, что к каждой из групп применяются схожие правила обработки. Как я уже сказал -- аппаратные ошибки (системные) -- на уровне средней программы исправить скорее всего не удастся. Так что аппаратные ошибки в 90% случаев никак не обрабатываются. Ошибки нарушения контракта/инварианта однозначно говорят о кривости кода (без вариантов). Ошибки связанные с корректностью/правильной последовательностью данных уже связаны с внешним источником -- причин может быть множество.

Четкая структуризация -- залог успеха.

git>1. Все исключения должны логироваться + как можно больше данных приведших к ним. Т.е. если была ошибка в базе данных то не плохо было бы видеть сам "плохой" запрос, данные по результатам которых он был сформирован и (на сервере) исходный входящий запрос. При тестировании можно, грубо говоря, запускать батник и проверять что до запуска приложения и после остановки лог пустой, очистка лога на совести человека.


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

git>2. Для пользователя надо постараться извернуться и показать какие именно его действия привели к ошибке и как её исправить. И здесь на самом деле не так важно системная ли эта ошибка или входных данных. На сервере разумеется нужно вернуть сообщение как можно менее раскрывающее внутреннее устройство и возможные уязвимости (на клиенте на самом деле тоже, но выбирая между удобством и паранойей я склоняюсь в сторону удобства).


Внимание! Действие пользователя не может привести к системной ошибке. Только к ошибке данных.

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


Дело даже не в разрешении ситуации на лету по базовому классу (хотя и это возможно иногда) а в лучшей СТРУКТУРИЗАЦИИ. Это очень важно.

Ошибки кода, к примеру, можно сразу отправлять разработкчику. Это 100% его вина. А вот ошибки работы с данными -- под вопросом. Можно даже детали вывести пользователю -- не все дураки, многие поймут в чем дело.
Re[2]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 12.08.10 05:55
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>У меня другая струтуризация.


Q>1) Logic Exceptions. То, что порождается ассертами, проверка инвариантов. Типа, «Мамой клянусь, в этом состоянии эта переменная должна быть чётной по построению!» Этот тип исключений не обрабатывается в catch-блоке; реакция на этот тип исключений заключается в баг-репорте автору библиотеки.


Т.е. просто запись в лог и никакой реакции? А вдруг что-то важное? Или программу закрываете?

Q>2) Usage Exception. Порождается при невыполнении контрактов того или иного метода со стороны вызывающего кода. Скажем, метод библиотеки умеет работать только с непустыми строками, и поэтому бросает ArgumentException, если параметр String.IsNullOrWhitespace. Это не проверка правильности аргументов, это проверка того, что правильность аргументов была проверена вызывающим кодом. Этот тип исключений не обрабатывается в catch-блоке; реакция на этот тип исключений заключается в предварительной проверке в пользовательском коде перед вызовом метода выполнения предусловий. Желательно, чтобы текст сообщений состоял из двух предложений: «Что произошло. Как исправить вызывающий код, чтобы исключение не выбрасывалось.»


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

Почему не обрабатываете в cathc? Что пользователь увидит? Системное сообщение об ошибке?

Q>3) Runtime Exception (название, быть может, не самое удачное). Исключения, которых нельзя избежать в дизайн-тайме. Скажем, FileNotFoundException: ты не можешь проверкой существования файла перед вызовом метода гарантировать, что этот файл будет существовать в следующий момент времени. Именно этот тип исключений обрабатывается в catch-блоке: оборачивается, заменяется, пробрасывается, останавливается.


Это ошибка обработки данных. #1. Файл может не существовать, может иметь некорректный формат и пр.

Q>4) System Failures. Часто, единственной реакцией является FastFail. Скажем, при OutOfMemoryException поздно пить боржоми, возможности обработать исключение может и не быть. Этот тип исключений, имхо, должен пробрасываться до самого внешнего кода.


Это мой #3 -- системная ошибка.
Re[6]: Парадигма работы с исключениями
От: 0K Ниоткуда  
Дата: 12.08.10 06:00
Оценка:
Здравствуйте, samius, Вы писали:

S>Хорошо бы чтобы программа сказала что я не могу прочитать эти данные, а не о том что данные не корректны для неё.


Разницы нет. Что вы напишите пользователю -- ваше дело. Суть в том, что для программы данные не корректны.

S>Т.е. ты предлагаешь сделать так, что бы например grep анализировал регулярность грамматики входной строки и выкидывал исключение "некорректные данные" в случае чего? Или система должна определить что grep содержит ошибку и не может обработать входную строку?


Причем здесь это? Мы говорим просто о структуризации типов исключений.

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

S>Как система узнает что состояние объекта испорчено-то?


Контракты и инварианты системы и ваши контракты. К примеру вышли за границу массива или вызвали метод пустого объекта.
Re[3]: Парадигма работы с исключениями
От: Qbit86 Кипр
Дата: 12.08.10 06:21
Оценка:
Здравствуйте, 0K, Вы писали:

Q>>1) Logic Exceptions...

Q>>2) Usage Exceptions...

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

Q>>1) Logic Exceptions... Этот тип исключений не обрабатывается в catch-блоке; реакция на этот тип исключений заключается в баг-репорте автору библиотеки.


0K>Т.е. просто запись в лог и никакой реакции? А вдруг что-то важное? Или программу закрываете?


Если ты используешь функцию сложения в сторонней библиотеке, а она по ошибке вычитает — твои действия? В лог? Окно сообщения? Закрыть программу?
Такие ошибки должны выявляться при тестировании, и глючной 3rd-party-метод просто не используется. В лог (в рантайме) нет особого смысла писать то, что известно в дизайн-тайме (метод не работает). А так — да, где-то у дна стека вызовов обычно есть обработчик неперехваченных исключений, который, например, показывает message box и логирует (программа не падает, но и запрошенная операция не выполняется). Но это ненормальная обработка, при выявлении проблем первых двух типов они должны быть устранены правкой кода.

Q>>2) Usage Exceptions... Этот тип исключений не обрабатывается в catch-блоке; реакция на этот тип исключений заключается в предварительной проверке в пользовательском коде перед вызовом метода выполнения предусловий...


0K>Ок. Эти исключения в начале метода, скажем ArgumentException созданы для пользователя или для разработчика? Поймет ли пользователь по тексту ошибки что произошло? Или просто увидит имя аргумента, которые для него ничего не значит?


Под «пользователем» везде выше я подразумевал разработчика, использующего стороннюю библиотеку, которая бросает исключения. Да, сообщение исключения должно быть таким, чтобы 1) пользователь (разработчик-пользователь библиотеки) понял, в чём проблема; 2) пользователь понял, как её избежать (а не обработать).

0K>Почему не обрабатываете в cathc?


Потому что обрабатываю в if. Утрированный пример:
Так нельзя:
try
{
  ...
  CheckIfExists(login);
  ...
}
catch (ArgumentException ex)
{
  MessageBox.Show("Login must not be empty.");
}

Так можно:
if (String.IsNullOrWhitespace(login))
{
  MessageBox.Show("Login must not be empty.");
}
else
{
  ...
  CheckIfExists(login);
  ...
}


Q>>3) Runtime Exceptions (название, быть может, не самое удачное). Исключения, которых нельзя избежать в дизайн-тайме. Скажем, FileNotFoundException: ты не можешь проверкой существования файла перед вызовом метода гарантировать, что этот файл будет существовать в следующий момент времени. Именно этот тип исключений обрабатывается в catch-блоке: оборачивается, заменяется, пробрасывается, останавливается.


0K>Это ошибка обработки данных. #1. Файл может не существовать, может иметь некорректный формат и пр.


Наоборот. «Ошибка обработки данных» — это частный случай runtime exception. Я свою иерархию не с потолка брал, примерно в таком виде она расписана во «Framework Design Guidelines», 2nd ed. (Но в классах FCL эта иерархия не отражена.)
Глаза у меня добрые, но рубашка — смирительная!
Re[3]: Парадигма работы с исключениями
От: git  
Дата: 12.08.10 06:57
Оценка: 1 (1)
Здравствуйте, 0K, Вы писали:

0K>Попытку записи в защищенную память отнести к нарушению инварианта?

В большинстве случаев наверное — да

0K>Или попытку привести объект к несовместимому типу?

Здесь уже возможно больше разнообразия — если сигнатура интерфейса скажем требует object, а мы пусть и не явно ожидаем что будет передан Button, то передача чего-то другого — нарушение контракта.

0K>Еще подумайте как сделать так, чтобы в лог не попали приватные данные (если финансовая система).

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

0K>Внимание! Действие пользователя не может привести к системной ошибке. Только к ошибке данных.

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

0K>Дело даже не в разрешении ситуации на лету по базовому классу (хотя и это возможно иногда) а в лучшей СТРУКТУРИЗАЦИИ. Это очень важно.

Согласен — важно. Но важно скорее не для обработки ошибок, а для общих правил разработки, чтобы у всех было представление какое исключение когда кидается.
Re: Парадигма работы с исключениями
От: fin_81  
Дата: 12.08.10 10:28
Оценка:
Почти похоже на мою классификацию:

Разработчик отвечает за работу определенной функции (или класса, или модуля, или тп). Его функция использует сторонние функции. Его функцию используют другие функции. Отсюда 3 вида ошибок:
1. "Логические" — ошибки внутри моей функции, вызванные неправильным использованием сторонних функций (см п.3). Пытаемся скрыть свои ошибки, логируем (предупреждение), возвращаем результат. Если не получается логируем(ошибка), возвращаем "нашу" ошибку.
2. "Системные" — ошибки в сторонних функциях. Пробуем другие варианты выполнения нужного действия, логируем (предупреждение), возвращаем результат. Если не получается — логируем(ошибка), пробрасываем дальше.
3. "Пользовательские" — ошибки неправильного использования нашей функции. Логируем(отладка), возвращаем ошибку неправильного использования.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.