Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Правильная обработка исключений 
:(
    Опции темы
drug007
Дата 16.1.2013, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Ну если на данном уровне можно обработать 20 исключений, нужно их обрабатывать - у Страуструпа это же четко обозначено. Но если в одном месте вылетает 20 разнотипных исключений то это проблема архитектуры, но не самих исключений. Потому что это значит, что в кучу смешано слишком много разного. Смысл их собирать столько на одном уровне?
PM MAIL   Вверх
EvilsInterrupt
Дата 16.1.2013, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



drug007, 
Все еще продолжаем обсуждение Вопроса №4.

Цитата(drug007 @  16.1.2013,  15:22 Найти цитируемый пост)
Смысл их собирать столько на одном уровне? 

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

Построим дерево вызовов:

0) super_future():
1) ....parser.parse()
2) ........semantic_something_doing()
3) ............syntax_something_doint()
4) ................read_char()
5) ....................open_file()
6) ....................read_file()

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

PM MAIL WWW ICQ Jabber   Вверх
bsa
Дата 16.1.2013, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



EvilsInterrupt, в данном случае почти все исключения должны иметь одного общего предка parse_error (метод what() возвращает текст с ошибкой и местом в файле). Таким образом, вышестоящий код (уровень 0 или меньше) перехватывает только его. Этому коду, если честно, сильно фиолетово, из-за чего не удалось распарсить файл (вряд ли он будет этот файл исправлять). Главное, что распарсить не удалось, а дальше уже пусть разбирается пользователь по представленной в ошибке информации.
А вот с ошибкой ввода/вывода сложней. Она к парсингу отношения не имеет и, по хорошему, ввод вывод следует осуществлять вне парсера. Но это неудобно.
В итоге, тебе необходимо сделать только два catch блока, для отлова ошибок ввода/вывода и парсинга. В принципе, если действия будут одинаковыми, то может будет иметь смысл тупо ловить std::exception и все.
PM   Вверх
EvilsInterrupt
Дата 16.1.2013, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



bsa, 
Ок. 

А что если ввести концептуальные уровни(не знаю как это проще назвать) попробую пояснить:

Концептуальный уровень 1: уровни 1, 2, 3 - это уровни парсинга
Концептуальный уровень 2: уровни 4, 5, 6 - это уровни ввода-вывода

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

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

Насколько такое применимо на практике?

ЗЫ:
Спрашиваю то что еще не применял на практике и это лишь мои догадки
PM MAIL WWW ICQ Jabber   Вверх
bsa
Дата 16.1.2013, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(EvilsInterrupt @  16.1.2013,  16:30 Найти цитируемый пост)
Насколько такое применимо на практике?

Имхо, вопрос не очень корректный. Это может быть применимо. Другое дело, что такое делать не стоит.
PM   Вверх
baldina
Дата 16.1.2013, 17:18 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(drug007 @  16.1.2013,  14:22 Найти цитируемый пост)
20 разнотипных исключений то это проблема архитектуры

разнотипных исключений нужно примерно столько, сколько требуется разных реакций на них.
Цитата(EvilsInterrupt @  16.1.2013,  15:30 Найти цитируемый пост)
А что если ввести концептуальные уровни

если почти все исключения приводят к сообщению об ошибке, то польза от уровней может быть только в детализации сообщений. скорее всего оно того не стоит
PM MAIL   Вверх
drug007
Дата 16.1.2013, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Цитата(baldina @  16.1.2013,  17:18 Найти цитируемый пост)
разнотипных исключений нужно примерно столько, сколько требуется разных реакций на них.

Это да, можно и больше. Но не для обработки же в одном месте!

Хоть bsa и ответил уже, повторю его ответ
0) super_future():
<-------- ошибка парсинга
1) ....parser.parse()
2) ........semantic_something_doing()
3) ............syntax_something_doint()
<-------- здесь только ошибка ввода-вывода
4) ................read_char()
5) ....................open_file()
6) ....................read_file()
т.е. только два типа исключений мы можем здесь обработать. Более того, если это библиотека не факт, что их вообще нужно обрабатывать.
Концептуальные уровни обязательно должны присутствовать - собственно разные класс, унаследованные от exception для этой цели и служат. Но обрабатывать исключение нужно только если действительно это нужно по бизнес-логике, например часть ошибки может устранена на текущем уровне, а остальное = на более высоком. Перехватывать просто с подменой класса исключения напрасная трата времени, имхо. В Вашем примере я бы перехватывал исключение ввода-вывода и выбрасывал взамен ошибку ввода-вывода только в том случае, если имя файла формируется внутри super_feature, если же параметры файла передаются извне, то и перехватывать не нужно.
PM MAIL   Вверх
baldina
Дата 17.1.2013, 08:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(drug007 @  16.1.2013,  20:55 Найти цитируемый пост)
Цитата(baldina @  16.1.2013,  17:18 )
разнотипных исключений нужно примерно столько, сколько требуется разных реакций на них.

Это да, можно и больше. Но не для обработки же в одном месте!

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

Стратегия обработки сообщений может быть разной; вполне возможно и нормально для большой группы исключений иметь один обработчик. Без описания конкретной задачи и архитектуры сказать хорошо это или нет нельзя.
PM MAIL   Вверх
drug007
Дата 17.1.2013, 08:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Цитата(baldina @  17.1.2013,  08:12 Найти цитируемый пост)
Без описания конкретной задачи и архитектуры сказать хорошо это или нет нельзя. 

Трудно не согласиться. Но я бы в любом случае избегал бы такого развития событий, какая бы архитектура и задача не была. Если уж только legacy code заставляет, либо "тяп-ляп" сделать достаточно.
PM MAIL   Вверх
EvilsInterrupt
Дата 17.1.2013, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Ок, спасибо за обсуждение по Вопросу №4.

Вопрос №5:

От какого базового типа лучше всего создавать свою иерархию исключений в библиотеки? От своего или от std::exception и почему?

Я видел проект, которые имел свой BaseException с методом where() в котором возвращались __LINE__, __FILE__, __FUNCTION__ . Но если честно, то на практике это не шибко может помочь, ведь если возникла ошибка, то можно поставить брякпоинт глядя на callstack в окне отладчика
PM MAIL WWW ICQ Jabber   Вверх
bsa
Дата 17.1.2013, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



EvilsInterrupt, в любом случае лучше наследоваться от std::exception. Так как код, который будет использовать твою либу, может понятия не иметь о твоих исключениях. Более того, в линухе есть стандартный перехватчик исключений, который поддерживает метод what у std::exception.
PM   Вверх
drug007
Дата 18.1.2013, 07:22 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Цитата(EvilsInterrupt @  17.1.2013,  18:56 Найти цитируемый пост)
От какого базового типа лучше всего создавать свою иерархию исключений в библиотеки? От своего или от std::exception и почему?

Люди писали проект, обрабатывали исключения-наследники std::exception и тут нашли Вашу замечательную библиотеку. А у нее своя иерархия исключений и, соответственно, чтобы их обрабатывать, им придется переписывать свой код и добавлять поддержку Ваших исключений. В их глазах это может оказаться серьезным аргументом против.
PM MAIL   Вверх
bsa
Дата 18.1.2013, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Но если очень хочется использовать свою иерархию, то можно сделать свой базовый класс наследником std::exception. В этом случае, и волки сыты, и овцы целы.
PM   Вверх
EvilsInterrupt
Дата 18.1.2013, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Цитата

В их глазах это может оказаться серьезным аргументом против. 

Я придя в один проект увидел достаточно стройную библиотеку. Библиотека написана силами команды компании. Однако там свой собственный Exception класс, от которого наследуются все типы исключений. На вопрос: "Почему?" получаю ответ "Так исторически сложилось, лет 10 назад С++ был далеко не тем чем является сейчас. Более того даже STL был далеко от того состояния чтобы его можно было использовать в проектах". Но тут же добавили "Если бы подобный выбор стоял сейчас, конечно мы бы наследовались от std::exception". 

Но я не понимаю: Что в этом классе такого? Ведь есть риск смешать свои ошибки с ошибками стандартной библиотеки.
PM MAIL WWW ICQ Jabber   Вверх
drug007
Дата 18.1.2013, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Цитата(EvilsInterrupt @  18.1.2013,  14:16 Найти цитируемый пост)
Но я не понимаю: Что в этом классе такого? Ведь есть риск смешать свои ошибки с ошибками стандартной библиотеки. 

Каким образом Вы смешаете? Класс std::exception он один такой, другого такого класса нет. Или Вы имеете в виду, что перехватывая std::exception Вы "случайно" перехватите другое исключение? Так для этого и предназначена иерархия. А если Вам надо перехватить наследника std::exception, то в начале делаете перехват наследника, а следующим делаете перехват std::exception. В нем ничего нет особенного, кроме того что он наследник для всех остальных. Не забывайте, что если Вы забудете перехватить исключение, то программа просто упадет с непонятной ошибкой (если обработчик не установите - то это нужно понимать для чего вы так делаете), а наследуясь от std::exception вы гарантируете, что все исключения будут обработаны.
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0547 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.