В настоящее время я создаю библиотеку, которая анализирует определения XML для конфигураций оборудования (полученные от производителя). Я сопоставил типы XML с классами c ++, и я использую std::optional
там, где есть необязательный член XML, когда семантически правильно пропустить этот фрагмент данных.
Iсейчас пытаюсь придумать хорошую стратегию обработки ошибок для моих типов данных. Иногда в XML может отсутствовать некоторая информация, помеченная схемой как required
, или не может быть найден обязательный элемент (что будет отличаться от ошибки в элементе, в котором отсутствуют обязательные данные).
Основная идея для всех типов следует этому (примеру) классу:
class TMyXmlType {
std::string name;
std::optional<int> factor;
std::optional<int> minFactor;
std::optional<int> maxFator;
public:
TMyXmlType(const xml_node & root){
if(root){ // Check if the element exists
name = root.value();
if(root.has_child("factor"){ factor = root.child("factor").value(); }
if(root.has_child("minFactor"){ factor = root.child("minFactor").value(); }
if(root.has_child("maxFator"){ factor = root.child("maxFator").value(); }
}else{
// What do I do here?
}
}
operator Json::Value() const {
if(/*object constructed correctly?*/){
Json::Value asJson;
asJson["name"] = name;
if(factor.has_value()){ asJson["factor"] = factor.value(); }
if(minFactor.has_value()){ asJson["minFactor"] = minFactor.value(); }
if(maxFator.has_value()){ asJson["maxFator"] = factor.maxFator(); }
return asJson;
}else{
// return error object?
}
}
}
Пока все хорошо. О дополнительных членах заботятся. Однако root
может быть пустым узлом (библиотека синтаксического анализа xml возвращает пустой узел, если он не был найден). В основном я хочу вернуть объект ошибки вместо значения класса (в моей операторной функции), если один или несколько требуемых узлов XML не были найдены.
Насколько я смог найти, для современныхВ C ++ вы должны выбросить исключение, если конструктор не может правильно сконструировать объект, однако, если я сгенерирую исключение, мои агрегированные типы данных будут иметь массивные конструкторы с кучей блоков try / catch для каждого необходимого элемента данных,что сделало бы кодовую базу трудной для чтения и поддержки.
Итак, теперь возникает вопрос: каков был бы самый чистый способ заставить оператор возвращать объект ошибки вместо данных класса, если требуемый членотсутствует?
Мне не нужен конструктор для явного сбоя, в настоящее время он также не будет выдавать (насколько я знаю), и я действительно хочу, чтобы объекты ошибок передавались вызывающей стороне вместо кодов возврата или всплывающих исключений.