简体   繁体   English

错误处理:区分“致命”错误和“意外输入”错误

[英]Error handling: distinguishing between 'fatal' errors and 'unexpected input' errors

I've been working on a program that reads in an XML file, and if ifstream is unable to open the file, it will throw std::ifstream::failure.我一直在开发一个读取 XML 文件的程序,如果 ifstream 无法打开该文件,它将抛出 std::ifstream::failure。 This exception is thrown whenever std::ifstream::failbit is set or std::ifstream::badbit is set, and they are (at least in my opinion) the type of errors that warrant exception handling.每当设置 std::ifstream::failbit 或设置 std::ifstream::badbit 时都会引发此异常,并且它们(至少在我看来)是需要处理异常的错误类型。

After I open the file, I use RapidXML to create the DOM object, and its parse function will throw rapidxml::parse_error if it fails.打开文件后,我使用 RapidXML 创建 DOM object,如果解析失败,function 将抛出 rapidxml::parse_error。 This is the type of situation where the error isn't really fatal--it's just bad input.在这种情况下,错误并不是真正致命的——它只是错误的输入。 At any rate, I think it's still fair for rapidxml to throw an exception when it fails to parse the xml file, but even if I didn't think so, it doesn't really matter, because I don't have too many options.无论如何,我认为rapidxml在解析xml文件失败时抛出异常还是公平的,但即使我不这么认为,也无所谓,因为我没有太多选择. I could turn off exceptions in RapidXML, but then I'd still have to handle these exceptional cases manually, and it's just far easier to handle them via the exception mechanism.我可以在 RapidXML 中关闭异常,但是我仍然必须手动处理这些异常情况,而且通过异常机制处理它们要容易得多。 However, this is definitely a murky area;然而,这绝对是一个阴暗的领域。 the justification for rapidxml::parse to throw exceptions isn't as clear-cut as it is for ifstream. rapidxml::parse 抛出异常的理由并不像 ifstream 那样明确。

The final case is when I'm parsing the DOM and come across an unexpected or unanticipated node.最后一种情况是当我解析 DOM 并遇到意外或未预料到的节点时。 Clearly, the program can continue executing in spite of unexpected input, but I wouldn't want it to.显然,尽管有意外的输入,程序仍可以继续执行,但我不希望它这样做。 I could conceivably throw an exception here, but I'm not sure if that makes much sense.我可以想象在这里抛出一个异常,但我不确定这是否有意义。

So, I'm asking for a little advice: what are some best practices for exception handling?所以,我想请教一个小建议:异常处理的一些最佳实践是什么? I try to use the RAII idiom in the class that parses files by doing all of this in the constructor.我尝试在 class 中使用 RAII 习语,通过在构造函数中执行所有这些来解析文件。 I use a boost::shared_ptr to instantiate the file parsing class, so if the constructor throws, boost::shared_ptr will rethrow std::bad_alloc after delete'ing the file parsing class.我使用 boost::shared_ptr 来实例化解析 class 的文件,因此如果构造函数抛出,boost::shared_ptr 将在删除解析 class 的文件后重新抛出 std::bad_alloc。

I can make an argument for having this occur when the XML file doesn't conform to what this class expects, and I suppose it would make sense to throw an exception when presented with unanticipated input, but I'd really just like to make sure that my thought process is correct.当 XML 文件不符合此 class 的预期时,我可以为发生这种情况提出一个论据,我认为在出现意外输入时抛出异常是有意义的,但我真的很想确保我的思维过程是正确的。

Your design makes good sense to me: Initialize completely or throw an exception.您的设计对我来说很有意义:完全初始化或抛出异常。 The only alternatives which come to mind are:唯一想到的选择是:

  • status codes状态码
  • best-effort initialization with status member functions to find out what portions are valid使用状态成员函数尽最大努力初始化以找出哪些部分是有效的

The only disadvantage which comes to mind for the all-or-nothing approach is dealing with "almost correct" input.全有或全无方法的唯一缺点是处理“几乎正确”的输入。 Maybe the application would prefer a default value if an attribute is missing.如果缺少属性,应用程序可能会更喜欢默认值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM