MSDN пишет про Exception'ы
От: BluntBlind  
Дата: 24.11.09 04:18
Оценка:
Последнее время частенько возникают вопросы по exception handling. В свое время тоже интересовался этой темой и нашел, что в MSDN есть список прописных истин, рекомендаций и типичных приемов по этому вопросу. Уверен, что даже имея большой опыт вы сможете найти там что-то новое для себя.
Объем там небольшой, прочитать можно за пол часа ну может час.

Обработка и создание исключений

Общие сведения об исключениях
Представлены общие сведения об исключениях среды CLR.

Класс Exception и его свойства
Описаны элементы объекта исключения.

Иерархия исключений
Описаны исключения, от которых наследуется большинство исключений.

Основы обработки исключений
Описаны методы обработки исключений с использованием операторов catch, throw и finally.

Лучшие методики обработки исключений
Описаны предлагаемые методы обработки исключений.

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

exception handling исключения обработка try catch msdn rtfm
Re: MSDN пишет про Exception'ы
От: Аноним  
Дата: 24.11.09 04:57
Оценка: -2
Здравствуйте, BluntBlind, Вы писали:

BB>Последнее время частенько возникают вопросы по exception handling. В свое время тоже интересовался этой темой и нашел, что в MSDN есть список прописных истин, рекомендаций и типичных приемов по этому вопросу. Уверен, что даже имея большой опыт вы сможете найти там что-то новое для себя.


Спасибо, поржал.

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

Re[2]: Перечитай внимательнее!
От: BluntBlind  
Дата: 24.11.09 05:09
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Спасибо, поржал.


А>

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


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

PS И дай ссылку на эту главу, обсудим.
Re[3]: Перечитай внимательнее!
От: Аноним  
Дата: 24.11.09 05:56
Оценка: -1
Здравствуйте, BluntBlind, Вы писали:

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

Мимо.

BB>Мой тебе совет, не позорься, перечитай!

Аккуратней на поворотах.

BB>PS И дай ссылку на эту главу, обсудим.

http://msdn.microsoft.com/ru-ru/library/seyhszts.aspx Только я не вижу, что тут можно обсуждать. Мне статья не понравилась, и некоторые места вызвали, как минимум, улыбку.
Re[4]: Еще разок Перечитай внимательнее!
От: BluntBlind  
Дата: 24.11.09 06:33
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, BluntBlind, Вы писали:

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

А>Мимо.
Что мимо? Давай аргументы, доводы.

BB>>Мой тебе совет, не позорься, перечитай!

А>Аккуратней на поворотах.
Меня задел твой емкий аргумент "спасибо, поржал". Давай конкретику...

BB>>PS И дай ссылку на эту главу, обсудим.

А>http://msdn.microsoft.com/ru-ru/library/seyhszts.aspx Только я не вижу, что тут можно обсуждать. Мне статья не понравилась, и некоторые места вызвали, как минимум, улыбку.
Какие места, почему?

На мой взгляд ты тролль. Залогинься и пиши конкретно твои за и против ...
аргументы
Re[5]: Еще разок Перечитай внимательнее!
От: Аноним  
Дата: 24.11.09 10:12
Оценка: 46 (6) -2
Здравствуйте, BluntBlind, Вы писали:

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

А>>Мимо.
BB>Что мимо?
Смешно не это.

BB>Меня задел твой емкий аргумент "спасибо, поржал".

Да он не к тебе относился, а к статье...

BB>Давай конкретику...

Держи. Вот для этой — http://msdn.microsoft.com/ru-ru/library/seyhszts.aspx статьи с амбициозным названием "Лучшие методики обработки исключений". Это мои мысли при ее прочтении. Там есть вопросительные знаки, но это вопросы не к тебе, а к статье, и по большинству риторические, отвечать на них не надо.

----------------------------------------------------

Необходимо четко представлять, когда следует устанавливать блок try/catch.

Думать вообще полезно...

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


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

В следующем примере показано использование оператора if для проверки закрытия подключения.
...

if(conn.State != ConnectionState.Closed)
      conn.Close();


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

if(доступноПамяти(Много))
  ЗабратьПамять(Много);



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


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

Если событие

Какое событие?

носит действительно исключительный характер

Как это проверить?

и представляет собой ошибку

1) Как это проверить? 2) Где определения терминов?

(например, неожиданно встретившийся конец файла)

Ага. Внезапно.

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


Т.е. если я хочу снизить количество кода, который выполняется при 'нормальном' потоке выполнения, то я должен использовать исключения. Хорошо... Но это единственный аргумент, который упомянут в статье, противоречит со смыслом существования ArgumentException / InvalidOperationException.

Используйте блоки try/finally

Какое откровение!

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

Почему нельзя в двух или трех? =)

При таком способе оператор try создает исключение

О как...

оператор finally закрывает или освобождает ресурсы

Сам?

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

Сам? Круто...

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

Это по делу. Но не для статьи с таким названием.

Имена классов исключений завершайте словом "Exception"

Почему не озвучены причины?

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

Это по делу. Но не для статьи с таким названием.

В C# и С++ при создании своих собственных классов исключений используйте по крайней мере три общих конструктора.

Это надо показать ребятам из rsdn.cpp

В большинстве случаев используйте предварительно определенные типы исключений.

Ага, значит есть еще меньшинство... Что же за этим скрывается?

Определяйте новые типы исключений только для программных сценариев.

Эээ....

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

Мысль я в принципе понял... но формулировка ни к черту.

Для большинства приложений унаследуйте пользовательские исключения от класса Exception.

Ага, значит есть еще меньшинство... Что же за этим скрывается?

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

Вот мысли по поводу 'изначально предполагалось' я бы почитал...

В каждое исключение включайте локализованную строку описания.

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

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

Как у нас статья называется? =)

Каждое предложение в строке описания должно заканчиваться точкой.

Не могу однозначно согласиться.

Обеспечьте программный доступ к свойствам Exception.

Существует другой?

Дополнительные сведения (кроме строки описания) включайте в исключение только в тех случаях, когда в соответствии со сценарием программирования такие дополнительные сведения могут оказаться полезными.

Что делать если набор сценариев использования неопределен?

Для наиболее общих и часто встречающихся ошибок следует возвращать пустое значение.

Сложность с определением "часто встречающихся".

Например, метод Open возвращает null, если файл не найден, но создает исключение, если этот файл заблокирован.

Для некоторых сценариев пойдет.

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

Что такое "нормальное использование"?

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

Вот она, неопределенность в действии. Да и SRP где-то рядом бродит...

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

Зачем в такой статье говорить об этом? Это же банальщина...

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

Что считать побочными эффектами? С определенной точки зрения даже получение локализованной строки может приводить к ним.

----------------------------------------
Повторю: это риторические вопросы.


BB>>>PS И дай ссылку на эту главу, обсудим.

А>>Мне статья не понравилась, и некоторые места вызвали, как минимум, улыбку.
BB>Какие места, почему?

Половина статьи — совершенно банальные вещи, терминология отсутствует, приведен просто набор правил "делай так". А между тем, лучшей методика может быть только в некотором контесте требований. И в любом случае она будет обладать какими-либо недостатками. Но анализа преимуществ/недостатков каждой "рекомендации" нет. На все возникшие вопросы предполагается ответить читателю. Хорошо если у него есть свое аргументированное мнение. Если же нет, то существует риск того, что описаное в статье станет для читателя набором догм, которым он будет слепо следовать.

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

BB>На мой взгляд ты тролль.

Я имел неосторожность высказать свои эмоции.
Re[6]: Еще разок Перечитай внимательнее!
От: Воронков Василий Россия  
Дата: 24.11.09 14:58
Оценка: 11 (2)
Здравствуйте, Аноним, Вы писали:

А>

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

А>Сам? Круто...

Мда, а я еще удивлялся, почему некоторые лепят блоки try/catch с пустым catch, а когда им показываешь на эту каку заявляют, что это-де "рекомендации", которые они где-то там прочитали. Блин, а оказывается и правда такое есть.

А>

В каждое исключение включайте локализованную строку описания.

А>И возбуждающий исключение код получит еще одну зависимость. Хотя это решаемо.

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

В этом плане разделение на GetError и GetErrorMessage мне кажется куда более логичным.
Re[7]: Еще разок Перечитай внимательнее!
От: BluntBlind  
Дата: 25.11.09 02:04
Оценка: -2
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Мда, а я еще удивлялся, почему некоторые лепят блоки try/catch с пустым catch, а когда им показываешь на эту каку заявляют, что это-де "рекомендации", которые они где-то там прочитали. Блин, а оказывается и правда такое есть.

Там нет таких рекомендаций и не было.

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

ВВ>В этом плане разделение на GetError и GetErrorMessage мне кажется куда более логичным.

На мой взгляд тут на лицо непонимание фундаментальных основ exception handling'а в .NET
1. Исключение не формирует сообщение об ошибках, оно его несет в себе в месте с другой информацией о возникшей проблеме.

2. Коды ошибок, энумерации и прочее. Все это лишнее для чистого .NET'а. Тип исключения, его класс, и есть тот самый код ошибки. Коды ошибок есть только из-за того, что .NET работает с системами из которых по другому не получишь информации об ошибках. Но при правильной архитектуре такие исключения (несущие код ошибки) должны быть разобраны и обернуты ПОДХОДЯЩИМ исключением на границе слоя, если они у вас есть

3. Message как раз и был сделан для того, чтобы нести описание и детали ошибки написанные человеческим языком. Просто не надо думать, что это сообщения для конечного пользователя. Это сообщения для лога, администратора, программиста и да для конченого пользователя, но не всегда.
Re: Обсуждаем
От: BluntBlind  
Дата: 25.11.09 03:25
Оценка:
Ответ на сообщение <b>Аноним </b><i>351</i>
Автор:
Дата: 24.11.09

Там просто не сразу разговор сложился.

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

Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, BluntBlind, Вы писали:

А>

Необходимо четко представлять, когда следует устанавливать блок try/catch.

А>Думать вообще полезно...
А>

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

А>Можно так, а можно эдак... Без анализа критериев статья ставит читателя в положение буриданова осла.

Это все вводные слова. Так сказать создание контекста обсуждаемой проблемы. Да можно и так и эдак, и далее объясняется как же выбрать нужный подход.

А>

В следующем примере показано использование оператора if для проверки закрытия подключения.
А>...
А>

А>if(conn.State != ConnectionState.Closed)
А>      conn.Close();
А>

А>Этот пример показывает как можно избежать возникновения исключения при вызове Close. Тем не менее при таком подходе вообще я вижу здесь суслика, о котором ничего не сказано. Суслик аналогичен такому:
А>
if(доступноПамяти(Много))
А>  ЗабратьПамять(Много);

А>

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

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

Если событие

А>Какое событие?
А>

носит действительно исключительный характер

А>Как это проверить?
А>

и представляет собой ошибку

А>1) Как это проверить? 2) Где определения терминов?
А>

(например, неожиданно встретившийся конец файла)

А>Ага. Внезапно.
А>

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

А>Т.е. если я хочу снизить количество кода, который выполняется при 'нормальном' потоке выполнения, то я должен использовать исключения. Хорошо... Но это единственный аргумент, который упомянут в статье, противоречит со смыслом существования ArgumentException / InvalidOperationException.

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

А>

Используйте блоки try/finally

А>Какое откровение!
А>

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

А>Почему нельзя в двух или трех? =)
А>

При таком способе оператор try создает исключение

А>О как...
А>

оператор finally закрывает или освобождает ресурсы

А>Сам?
А>

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

А>Сам? Круто...
Пустые придирки ...

А>

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

А>Это по делу. Но не для статьи с таким названием.

А>

Имена классов исключений завершайте словом "Exception"

А>Почему не озвучены причины?

Это рекомендация. Так принято. В конце имени класса указывать имя базового класса. Не доходи до маразма с вопросами

А>

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

А>Это по делу. Но не для статьи с таким названием.

А>

В C# и С++ при создании своих собственных классов исключений используйте по крайней мере три общих конструктора.

А>Это надо показать ребятам из rsdn.cpp
ctor()
ctor(string message)
ctor(string message, Exception inner)
Очень нужная рекомендация.

А>

В большинстве случаев используйте предварительно определенные типы исключений.

А>Ага, значит есть еще меньшинство... Что же за этим скрывается?
А>

Определяйте новые типы исключений только для программных сценариев.

А>Эээ....
А>

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

А>Мысль я в принципе понял... но формулировка ни к черту.
Это да

А>

Для большинства приложений унаследуйте пользовательские исключения от класса Exception.

А>Ага, значит есть еще меньшинство... Что же за этим скрывается?
А>

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

А>Вот мысли по поводу 'изначально предполагалось' я бы почитал...
Раньше MSDN советовал, что бы свои классы исключений наследовались от ApplicationException, но эта практика не прижилась, да и вообще нормальный exception handling в проектах это скорее исключение чем правило. А не прижилось наверно из-за дурацкого названия Application ...

А>

В каждое исключение включайте локализованную строку описания.

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

А>

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

А>Как у нас статья называется? =)
А>

Каждое предложение в строке описания должно заканчиваться точкой.

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

А>

Обеспечьте программный доступ к свойствам Exception.

А>Существует другой?

А>

Дополнительные сведения (кроме строки описания) включайте в исключение только в тех случаях, когда в соответствии со сценарием программирования такие дополнительные сведения могут оказаться полезными.

А>Что делать если набор сценариев использования неопределен?
Не включать дополнительные параметры, либо включить те, которые будут определены в большинстве случаев. Серебряной пули нет!

А>

Для наиболее общих и часто встречающихся ошибок следует возвращать пустое значение.

А>Сложность с определением "часто встречающихся".
А>

Например, метод Open возвращает null, если файл не найден, но создает исключение, если этот файл заблокирован.

А>Для некоторых сценариев пойдет.

А>

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

А>Что такое "нормальное использование"?
Ниже объясняется:

А>

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

А>Вот она, неопределенность в действии. Да и SRP где-то рядом бродит...

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

А>

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

А>Зачем в такой статье говорить об этом? Это же банальщина...
Это не банальщина, я вообще видел мало кода, который бы так делал.

А>

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

А>Что считать побочными эффектами? С определенной точки зрения даже получение локализованной строки может приводить к ним.
Аккуратно писать такие методы и как можно проще. Если не удалось извлечь локализованную строку, подставь дефолтную...

А>----------------------------------------

А>Повторю: это риторические вопросы.
Мне они не показались риторическими. Вообще раздражает твоя манера задавать вопрос на каждое предложение, в то время когда смысл несет целый абзац статьи.
Re[6]: Еще разок Перечитай внимательнее!
От: BluntBlind  
Дата: 25.11.09 04:02
Оценка: -1
Тут я ответил на вопросы, которые ты почему-то посчитал риторическими, но они такими не были
Автор: BluntBlind
Дата: 25.11.09
. Предлагаю там вести конструктивный диалог, а в этой ветке пофлудим, если есть желание

А>Половина статьи — совершенно банальные вещи, терминология отсутствует, приведен просто набор правил "делай так". А между тем, лучшей методика может быть только в некотором контесте требований. И в любом случае она будет обладать какими-либо недостатками. Но анализа преимуществ/недостатков каждой "рекомендации" нет. На все возникшие вопросы предполагается ответить читателю. Хорошо если у него есть свое аргументированное мнение. Если же нет, то существует риск того, что описаное в статье станет для читателя набором догм, которым он будет слепо следовать.

А>Если бы у статьи было бы другое название, то возможно я бы ее и не стал читать...
Да название слишком вызывающее. Но я вообще-то предупреждал:

В свое время тоже интересовался этой темой и нашел, что в MSDN есть список прописных истин, рекомендаций и типичных приемов по этому вопросу.

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

BB>>На мой взгляд ты тролль.

А>Я имел неосторожность высказать свои эмоции.
Ты вообще довольно эмоциональный человек я заметил
Re[2]: Обсуждаем
От: Аноним  
Дата: 25.11.09 06:25
Оценка:
Здравствуйте, BluntBlind, Вы писали:

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


+1.

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


Что-нибудь большое и по делу я бы с удовольствием почитал....

BB>Это все вводные слова. Так сказать создание контекста обсуждаемой проблемы. Да можно и так и эдак, и далее объясняется как же выбрать нужный подход.


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

А>>Т.е. если я хочу снизить количество кода, который выполняется при 'нормальном' потоке выполнения, то я должен использовать исключения. Хорошо... Но это единственный аргумент, который упомянут в статье, противоречит со смыслом существования ArgumentException / InvalidOperationException.


BB>Пример. Ты пишешь парсер. Предположим он находится в позиции и состоянии когда ожидается еще наличие данных и ты должен продолжить чтение. Вот стоит ли тут делать проверку на конец файла/потока? Ответ нет. Так как для твоего алгоритма в данном месте конец данных — это не типичная ситуация и ее нужно обрабатывать как исключительную.


Поток оборачивается другим потоком, который при достижении end-of-file выплевывает что-то вроде tokenSpace. Таким образом разбор незакрытого строкового литерала закончится сообщением "неверный литерал" а не "недостаточно данных". + tokenEOF, поскольку там будут проверки вроде "сейчас ждем этот, этот и вот этот, а все остальные — ошибка такая-то". tokenEOF прекрасно подпадает под "все остальные", а с исключением (при EOF) ты замучеешся генерировать вменямые сообщения об ошибках.

А>>

оператор finally закрывает или освобождает ресурсы

А>>Сам?
А>>

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

А>>Сам? Круто...
BB>Пустые придирки ...

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

А>>

Имена классов исключений завершайте словом "Exception"

А>>Почему не озвучены причины?

BB>Это рекомендация. Так принято. В конце имени класса указывать имя базового класса.

Принято — это когда в coding style гвоздями прибито. Хотя здесь придрался, согласен.

А>>

В C# и С++ при создании своих собственных классов исключений используйте по крайней мере три общих конструктора.

А>>Это надо показать ребятам из rsdn.cpp
BB>ctor()
BB>ctor(string message)
BB>ctor(string message, Exception inner)
BB>Очень нужная рекомендация.

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

А>>

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

А>>Вот мысли по поводу 'изначально предполагалось' я бы почитал...
BB>Раньше MSDN советовал, что бы свои классы исключений наследовались от ApplicationException, но эта практика не прижилась

Мне интересны рассуждения о том, почему 'изначально предполагалось'.

А>>

В каждое исключение включайте локализованную строку описания.

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

Можно так: в объекте исключения (прямо или косвенно) находится некоторый ID, по которому однозначно можно определить локализованную строку в ресурсах (да хоть где) с именованными плейсхолдерами. Дальше два варианта на выбор: объект исключения имеет функцию string Format(string fmt), в которой происходит само форматирование с использованием этой строки форматирования, либо объект исключения имеет методы для перечисления пар строк <ИмяПлейсхолдера, Значение>. Вуаля. Форматирование происходит в обработчике и полностью настраиваемо. Зависимости сведены в минимум — при форматировании по месту возбуждения необходимо завязываться на способ получения строки, в моем случае эта проблема отсутствует.

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

А>>

Каждое предложение в строке описания должно заканчиваться точкой.

А>>Не могу однозначно согласиться.
BB>Очень согласен с этим. Позволяет формировать единообразные абзацы сообщений из нескольких вложенных исключений.

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

А>>

Обеспечьте программный доступ к свойствам Exception.

А>>Существует другой?

А>>

Дополнительные сведения (кроме строки описания) включайте в исключение только в тех случаях, когда в соответствии со сценарием программирования такие дополнительные сведения могут оказаться полезными.

А>>Что делать если набор сценариев использования неопределен?
BB>Не включать дополнительные параметры, либо включить те, которые будут определены в большинстве случаев.

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

А>>Что такое "нормальное использование"?

BB>Ниже объясняется:

А>>

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

А>>Вот она, неопределенность в действии. Да и SRP где-то рядом бродит...

BB>Правильная рекомендация. Пользователь твоей функциональности должен иметь выбор — это раз. А два — ты не должен решать за пользователя твоей функциональности, что считать ошибкой, а что нет.


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


А>>

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

А>>Что считать побочными эффектами? С определенной точки зрения даже получение локализованной строки может приводить к ним.
BB>Аккуратно писать такие методы и как можно проще. Если не удалось извлечь локализованную строку, подставь дефолтную...

А вот и первые ласточки: у нас разные определения побочных эффектов. А что имелось ввиду в статье — фз, используемого определения-то и нет.

А>>Повторю: это риторические вопросы.

BB>Мне они не показались риторическими.

Это даже не сколько вопросы, сколько мои мысли. При прочтении я задавал эти вопросы сам себе и пытался найти ответы на них в статье — но безрезультатно. А поскольку мои ответы у меня уже были, то никакого конструктива в статье я не нашел. Хотя от статьи с таким названием — ожидал.

BB>Вообще раздражает твоя манера задавать вопрос на каждое предложение,


Ты же хотел конструктива...

BB>в то время когда смысл несет целый абзац статьи.


Который оперирует терминами, определения которым должен дать читатель ;( Из этого потом непонимание и появляется.
Re: MSDN пишет про Exception'ы
От: Pro100Oleh Украина  
Дата: 25.11.09 07:30
Оценка:

•Для наиболее общих и часто встречающихся ошибок следует возвращать пустое значение. Например, метод Open возвращает null, если файл не найден, но создает исключение, если этот файл заблокирован.


Не люблю такой подход, хотя использую, но обязательно при этом добавляю в имя метода суффикс "OrDefault" (типа GetStreamOrDefault). Как то попал на проэкт, где практиковалось это решение: я очень долго отлавливал ошибки NullReferenceException в местах, никак не связанными с истинными проблемами в коде.
Здесь проблема, в том, что метод GetStream пишет один програмер, а использвать может другой (или тот же, но позже, когда реализация метода забыта). Первый решил, что при возникшем исключении я лутче верну null (типа файл не найден и нечего возвращать), а сверху пусть сами думают, что с этим делать. Второй же ничего о null не подозревает и сразу же его использует.
Pro
Re[8]: Еще разок Перечитай внимательнее!
От: Воронков Василий Россия  
Дата: 25.11.09 10:19
Оценка: 1 (1) +1 -1
Здравствуйте, BluntBlind, Вы писали:


BB>На мой взгляд тут на лицо непонимание фундаментальных основ exception handling'а в .NET


Тут на лицо фундаментальное нежелание задуматься о чем-либо, кроме того, что написано в MSDN.
В классе исключения не нужно "описание" ошибки, которое к тому же тянет за собой завимость от локали. Там нужны данные о возникшем исключении и все. Если кто-то решил, что описывать эти данные "человеческим языком" это большой прогресс, то тут точно имеет место быть "фундаментальное непонимание" чего-то.
Re[7]: Еще разок Перечитай внимательнее!
От: Mr.Cat  
Дата: 25.11.09 10:42
Оценка: 1 (1)
Здравствуйте, Воронков Василий, Вы писали:
ВВ>А вот, кстати, интересно — зачем вообще в исключениях болтологические описания того, что произошло? Нужна лишь информация об ошибке — код, возможно, представленный в виде энумерации, и набор дополнительных аргументов. Ведь это не задача исключения формировать строку для показа ее в пользовательском интерфейсе.
Когда есть строка с описанием — это удобно. Если есть возможность сказать программисту, что и где он сделал не так — лучше уж сказать, чем заставлять его рыться в документации, на предмет того, что за "неведомая фигня №9000" у него произошла.
А вот насчет "автоматической" локализации текстов — вот это и правда спорный момент. Англоязычное сообщение об ошибке можно хотя бы программисту показать, а вот локализованное — ни юзеру, ни программисту может оказаться не нужно.
Re[9]: Код ошибки, Message
От: BluntBlind  
Дата: 25.11.09 11:02
Оценка:
Здравствуйте, Воронков Василий, Вы писали:
ВВ>В классе исключения не нужно "описание" ошибки, которое к тому же тянет за собой завимость от локали. Там нужны данные о возникшем исключении и все.

Еще раз:
-Код ошибки лишнее, если это не связанно с взаимодействием с системой, которая по-другому не умеет.
-Чтобы отличить одну ошибку от другой, достаточно типа исключения.
-Чтобы понять где произошло исключение, есть stack trace.
-Передача данных связанных с ошибкой предусмотрена и никакого отношения к Message это не имеет: Exception &mdash; члены
-При возникновении ошибки я всегда в первую очередь смотрю на Message. И в 99% случаев этого мне достаточно, чтобы понять что произошло. Это мой практический опыт, я не могу согласится, что Message — это лишнее. Да без него возможно обойтись, но я не хочу жить в таком мире


ВВ>Если кто-то решил, что описывать эти данные "человеческим языком" это большой прогресс, то тут точно имеет место быть "фундаментальное непонимание" чего-то.


Описывать данные "человеческим языком" — это твоя выдумка, никто этого не предлагал.
Re[8]: Еще разок Перечитай внимательнее!
От: Воронков Василий Россия  
Дата: 25.11.09 11:33
Оценка: 1 (1) +1
Здравствуйте, Mr.Cat, Вы писали:

MC>Здравствуйте, Воронков Василий, Вы писали:

ВВ>>А вот, кстати, интересно — зачем вообще в исключениях болтологические описания того, что произошло? Нужна лишь информация об ошибке — код, возможно, представленный в виде энумерации, и набор дополнительных аргументов. Ведь это не задача исключения формировать строку для показа ее в пользовательском интерфейсе.
MC>Когда есть строка с описанием — это удобно. Если есть возможность сказать программисту, что и где он сделал не так — лучше уж сказать, чем заставлять его рыться в документации, на предмет того, что за "неведомая фигня №9000" у него произошла.
MC>А вот насчет "автоматической" локализации текстов — вот это и правда спорный момент. Англоязычное сообщение об ошибке можно хотя бы программисту показать, а вот локализованное — ни юзеру, ни программисту может оказаться не нужно.

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

А вот при программном анализе мне "описание" ошибки не нужно. Нужны коды, энумерации и проч. А злоупотребление описаниями приводит часто к порочным практикам — когда ценная именно для обработки исключения информация содержится в строке, и ее нужно "выпарсивать".

Опять-таки я же не против того, чтобы был некий стандартный сервис — для "родных" же фреймворковских исключений — который бы эти самые "описания" мог предоставлять. Что-то типа:

ExceptionManager.GetDescription(Exception ex);

Вот такой подход мне кажется более правильным что ли. И никакой зависимости от локали, которая сейчас есть в полном объеме (а если мне с немецкого фреймворка дамп прислали — мне что, со словарем сидеть??).
Re[10]: Код ошибки, Message
От: Воронков Василий Россия  
Дата: 25.11.09 11:35
Оценка:
Здравствуйте, BluntBlind, Вы писали:

BB>-При возникновении ошибки я всегда в первую очередь смотрю на Message. И в 99% случаев этого мне достаточно, чтобы понять что произошло. Это мой практический опыт, я не могу согласится, что Message — это лишнее. Да без него возможно обойтись, но я не хочу жить в таком мире


Коды ошибки и сейчас есть. А Message это не лишнее, это то, что не должно быть частью логики генерации исключений и часть исключения самого по себе.


ВВ>>Если кто-то решил, что описывать эти данные "человеческим языком" это большой прогресс, то тут точно имеет место быть "фундаментальное непонимание" чего-то.

BB>Описывать данные "человеческим языком" — это твоя выдумка, никто этого не предлагал.

Ага, ты предлагал описывать Message нечеловеческим языком. Ну что ж, извините, не понял.
Re[9]: Еще разок Перечитай внимательнее!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.09 11:37
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Вот такой подход мне кажется более правильным что ли. И никакой зависимости от локали, которая сейчас есть в полном объеме (а если мне с немецкого фреймворка дамп прислали — мне что, со словарем сидеть??).


С немецкого — это еще повезло... С английским можно худо-бедно скореллировать.
Re[11]: Код ошибки, Message
От: BluntBlind  
Дата: 25.11.09 11:51
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Коды ошибки и сейчас есть. А Message это не лишнее, это то, что не должно быть частью логики генерации исключений и часть исключения самого по себе.

Ты про HResult ? Он protected и используется, как я понимаю, для совместимости с COM. Прошлое всегда идет за нами следом

ВВ>Ага, ты предлагал описывать Message нечеловеческим языком. Ну что ж, извините, не понял.

3. Message как раз и был сделан для того, чтобы нести описание и детали ошибки написанные человеческим языком.
Автор: BluntBlind
Дата: 25.11.09


Про данные я не говорил
Re[12]: Код ошибки, Message
От: Воронков Василий Россия  
Дата: 25.11.09 11:59
Оценка:
Здравствуйте, BluntBlind, Вы писали:

ВВ>>Коды ошибки и сейчас есть. А Message это не лишнее, это то, что не должно быть частью логики генерации исключений и часть исключения самого по себе.

BB>Ты про HResult ? Он protected и используется, как я понимаю, для совместимости с COM. Прошлое всегда идет за нами следом

Нет, я например, про код ошибки СУБД. Если на каждый код создавать по своему типу исключений, то для одной базы будет этак 500 разных исключений. Чего бы мне лично очень не хотелось. Хотя конечно сделать исключения для СУБД более рафинированными не помешало бы.

ВВ>>Ага, ты предлагал описывать Message нечеловеческим языком. Ну что ж, извините, не понял.

BB>3. Message как раз и был сделан для того, чтобы нести описание и детали ошибки написанные человеческим языком.
Автор: BluntBlind
Дата: 25.11.09


И на основе своего опыта работы с .NET с 2002 года и прекрасного секса с исключениями, а не на основе дурашливой статью из русского МСДН, я говорю, что это было ошибочным решением. "Детали ошибки написанные человеческим языком" никому не нужны, особенно если эти самые детали присутствуют лишь в локализованном сообщении. Пользователю нет дела до ваших IndexOutOfRange и прочей ерунды. Программисту нужен тип, аргументы, иногда уточняющий тип (код) и колл-стек.

BB>Про данные я не говорил


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

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

Argument 'xxx' cannot be a null reference.

И чем это лучше чем:

ArgumentNullReferenceException; ArgumentName='xxx'

А вот чем хуже я могу сказать.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.