IllegalStateException 可以用来捕获所有子异常吗?

发布于 2024-11-09 06:13:05 字数 1759 浏览 0 评论 0原文

我想知道在这种情况下使用 IllegalStateException 对于 API 来说是否是一个很好的设计选择。

场景: 我有一个函数可以检查 XML 文档是否格式良好,并具有以下签名:

public boolean isXMLDocumentWellFormed(InputStream inXMLDocument)

该函数使用以下代码片段来加载 XML 文档:

    boolean isXMLDocWellFormed = false;

    // Setup document builder
    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
            .newInstance();

    if (docBuilderFactory == null)
        throw new IllegalStateException(
                "The DocumentBuilderFactory cannot be instanciated");
    try {
        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();

        // Parse document
        Document doc = docBuilder.parse(inXMLDocument);

        if (doc != null)
            isXMLDocWellFormed = true;

    } catch (ParserConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException(e);
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException(e);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException(e);
    }

    return isXMLDocWellFormed;

API 的设计非常易于使用。 但是,我想向 API 用户提供了解为什么无法检查 XML 文档的可能性(例如:DocumentBuilderFactory 无法创建 DocumentBuilder 对象),而不会让他们因必须处理的大量检查异常而感到不知所措。

我对此设计的担忧是:

a)使用单一异常类型(即 IllegalStateException)返回每个可能捕获的异常以指示执行检查失败是一个好主意吗?我会说是,因为用户该函数有两件事除外:

  1. 了解 XML 文档的格式是否良好。
  2. 了解函数无法返回答案的情况(例如由于异常)函数未能提供答案的原因。

b) 如果 a) 的答案是否定的,那么最合适的异常名称或解决方案是什么以及为什么

问候,

I wonder if using an IllegalStateException in this scenario is a good design choice for an API.

Scenario:
I have a function which checks if an XML document is well formed with the following signature:

public boolean isXMLDocumentWellFormed(InputStream inXMLDocument)

This function uses the following snippet to load the XML document:

    boolean isXMLDocWellFormed = false;

    // Setup document builder
    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
            .newInstance();

    if (docBuilderFactory == null)
        throw new IllegalStateException(
                "The DocumentBuilderFactory cannot be instanciated");
    try {
        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();

        // Parse document
        Document doc = docBuilder.parse(inXMLDocument);

        if (doc != null)
            isXMLDocWellFormed = true;

    } catch (ParserConfigurationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException(e);
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException(e);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException(e);
    }

    return isXMLDocWellFormed;

The API is designed to be very easy to use. However, I would like to provide to API users the possibility to know why an XML document cannot be checked (example: DocumentBuilderFactory cannot create a DocumentBuilder object) without overwhelming them with tons of checked exception that they will have to deal with.

My concerns regarding this design are:

a) Does using one single Exception type (i.e IllegalStateException) to return every possible caught exceptions to indicate a failure to perform the check a good idea ? I would say yes since users would except 2 things out of this function:

  1. To know if the XML document is well formed or not.
  2. To know in the event that the function cannot return the answer (due to an exception for instance) why the function failed to provide the answer.

b) If the answer to a) is no, then what would be the most appropriate exception name or solution and why ?

Regards,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

人疚 2024-11-16 06:13:05

我对人们的第一个建议是不要仅仅为了有效地重新抛出而捕获异常。抓住你真正可以对它们做点什么的时候。所以想一想。但是在您捕获已检查异常并将其包装在运行时异常中的示例中,我会问一个问题 - 这种情况发生的频率是多少?如果异常可能很常见(或严重),那么您希望程序员确保他们处理它们,因此检查是可行的方法。但是,如果它们不常见(并且不严重),那么抛出包装运行时可能是可以接受的。这是您需要考虑的事情,因为没有什么比意外的异常更让开发人员烦恼的了。

说了这么多:-),如果你要换行,我会考虑创建你自己的异常,因为你想清楚它是你的,而不是 Java 的。您甚至可以创建一个层次结构,其中包含扩展运行时的通用异常,然后创建更具体的扩展通用异常的层次结构。因此,API 用户可以选择在不同级别进行捕获。

My first recommendation to people is to not catch exceptions just to effectively re-throw. Catch when you can actually do something about them. So think about that. But in your example where you are catching checked exceptions and wrapping them in a runtime exception, I'd ask the question - how often will this occur? If the exceptions are likely to be common (or serious) then you want programmers to ensure that they deal with them, so checked is the way to go. However if they are not common (and not serious) then throwing a wrapping runtime may be acceptable. This is something that you need to think about because nothing annoys a developer more than unexpected exceptions.

Having said nothing by saying all that :-) if you are going to wrap I'd consider creating your own exception because you want to be clear that it is yours and not Java's. You could even create a hierarchy with a generalised exception extending runtime, and then more specific ones extending your genralised exception. Thus allowing API users the option to catch at different levels.

傲影 2024-11-16 06:13:05

如果您开发的是一个 API,那么您应该将所有异常包装在一个主异常中。这样你就不会泄露实现细节。然而,您的个人品味可能会有所不同

,但我认为 IllegalStateException 不太适合这里。它非常通用并且不能解释问题(IO 异常是非法状态?)。最好的解决方案是创建您自己的自定义异常类并抛出它。

作为您或其他任何人的辅助节点,如果您抛出异常,请不要打印异常。

If its an API that your developing then you should wrap all exceptions in one main exception. This way you don't bleed implementation details. However your personal taste may differ

However I don't think IllegalStateException fits well here. Its very generic and doesn't explain the problem (An IO Exception is Illegal state?). Best solution is to create your own custom Exception class and throw that.

As a side node to you or anyone else, please don't print the exception if your throwing it.

樱娆 2024-11-16 06:13:05

我建议让例程泄漏四种类型的异常可能是最有帮助的:

  1. CleanFailureException:请求的操作失败,但该尝试没有任何副作用。从其自身的角度来看,抛出异常的实体预计处于有效状态,尽管它可能不符合类用户可能期望的某些不变量。示例:从字典中检索不存在的键。字典的数据结构可能是完全有效的,就像字典一样,但应用程序可能期望它处于包含所请求密钥的状态(也有可能字典处于正确的状态,并且其他原因给应用程序提供了错误的密钥) )。
  2. PartialOperationException:请求的操作未完成,但可能已完成到某种未知的程度。如上所述,从其自身的角度来看,抛出异常的实体可能处于有效状态,但调用者必须检查它是否处于调用者认为有效的状态。
  3. StateCorruptException:请求的操作未完成,并且尝试操作的对象或某些嵌套对象似乎具有损坏状态。
  4. SystemOnFireException:系统中任何事物的状态都应被视为可疑。

由数组索引越界等原因引起的异常可能属于上述任何类别。重要的不是访问了越界索引,而是它对其他对象意味着什么。捕获、包装和重新抛出将是一种非常有用的模式,因为将异常解析为上述类别之一将使调用者更好地了解如何处理它。

I would suggest that it's probably most helpful to have a routine leak four types of exceptions:

  1. CleanFailureException: The requested operation failed, but the attempt did not have any side-effects. The entity throwing the exception is expected to be in a valid state from its own perspective, though it's possible it does not comply with some invariants the user of the class may be expecting. Example: retrieving a non-existent key from a Dictionary. The Dictionary's data structures may be perfectly valid, as a Dictionary, but the application may expect it to be in a state containing the requested key (it's also possible that the Dictionary is in the right state, and something else gave the application a wrong key).
  2. PartialOperationException: The requested operation did not complete, but may have completed to some unknown degree. As above, the entity throwing the exception is probably in a valid state from its own perspective, but the caller will have to check whether it's in a state the caller would consider valid.
  3. StateCorruptException: The requested operation did not complete, and the object upon which it was attempted, or some nested object, seems to have a corrupt state.
  4. SystemOnFireException: The state of anything and everything in the system should be considered suspect.

An exception caused by something like an out-of-bounds array index could fall into any of the above categories. What matters is not that an out-of-bounds index was accessed, but rather what it means about other objects. Catch, wrap, and rethrow would be a very useful pattern, since resolving an exception into one of the above categories will give the caller a much better idea what to do with it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文