Обработка ошибок: различие между «фатальными» ошибками и ошибками «неожиданного ввода»

Я работал над программой, которая читает файл XML, и если ifstream не может открыть файл, она выдает std::ifstream::failure. Это исключение выдается всякий раз, когда устанавливается std::ifstream::failbit или std::ifstream::badbit, и они (по крайней мере, на мой взгляд) относятся к типу ошибок, требующих обработки исключений.

После того, как я открою файл, я использую RapidXML для создания объекта DOM, и его функция синтаксического анализа выдаст Rapidxml::parse_error в случае сбоя. Это тип ситуации, когда ошибка на самом деле не является фатальной — это просто неверный ввод. В любом случае, я думаю, что для rapidxml по-прежнему справедливо генерировать исключение, когда ему не удается разобрать файл xml, но даже если я так не думаю, это не имеет большого значения, потому что у меня не так много вариантов . Я мог бы отключить исключения в RapidXML, но тогда мне все равно пришлось бы обрабатывать эти исключительные случаи вручную, и гораздо проще обрабатывать их с помощью механизма исключений. Однако это определенно темная область; обоснование для Rapidxml::parse генерирования исключений не столь однозначно, как для ifstream.

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

Итак, я прошу небольшого совета: каковы лучшие методы обработки исключений? Я пытаюсь использовать идиому RAII в классе, который анализирует файлы, делая все это в конструкторе. Я использую boost::shared_ptr для создания экземпляра класса синтаксического анализа файлов, поэтому, если конструктор выдает исключение, boost::shared_ptr повторно сгенерирует std::bad_alloc после удаления класса синтаксического анализа файлов.

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


person kmore    schedule 11.07.2011    source источник
comment
RAII великолепен и все такое, но я предпочитаю тривиальные конструкторы. Если вы открываете файлы, подключаете сокеты или выполняете любую другую логику нераспределения, подверженную сбоям, в конструкторе, вам следует бросать.   -  person AJG85    schedule 11.07.2011
comment
Тривиальные конструкторы отлично подходят для тривиальных вещей, поскольку они не подвержены упомянутым вами исключительным случаям. Единственное, что я мог придумать, чтобы опровергнуть ваш аргумент в пользу тривиальных конструкторов, - это исключение нехватки памяти... это очень возможно в конструкторе, который выделяет память, но я полагаю, что когда вы говорите "тривиальный конструктор", вы, вероятно, не означает тот, который выделяет какую-либо память для членов класса.   -  person kmore    schedule 11.07.2011
comment
Я просто хотел указать, что наличие конструктора, который создает много объектов, открывает файлы, анализирует xml, проверяет входные данные на достоверность и т. д. и т. д., может также быть гигантской функцией «все», что для меня идет вразрез с объектно-ориентированными принципами.   -  person AJG85    schedule 12.07.2011


Ответы (1)


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

  • коды состояния
  • инициализация с наилучшими усилиями с функциями-членами состояния, чтобы узнать, какие части действительны

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

person wallyk    schedule 13.07.2011
comment
Спасибо за подтверждение. Природа ввода требует подхода «все или ничего», потому что, если есть какая-либо ошибка в способе форматирования файла, ничто другое в этом модуле не будет иметь никакого смысла. - person kmore; 14.07.2011