【问题标题】:Catching some exceptions but ignoring others - why doesn't this work?捕捉一些例外但忽略其他例外 - 为什么这不起作用?
【发布时间】:2011-04-02 08:12:49
【问题描述】:

我有类似的东西。

void func() {
  try {
    //socket disconnects in middle of ..parsing packet..
  } catch(Exception ex) {
   if(!ex.getMessage().toString().equals("timeout") || !ex.getMessage().toString().equals("Connection reset")) {
     debug("Exception (run): " + ex.getMessage());
     ex.printStackTrace();
  }
}

为什么当我收到连接重置异常或超时异常时,它仍然在条件内。我试过没有 toString,但没有运气。

【问题讨论】:

    标签: java exception string printstacktrace


    【解决方案1】:

    您不应该捕获所有异常然后测试异常的错误消息。相反,只捕获您打算处理的那些异常 - 例如SocketTimeoutException

    catch (SocketTimeoutException ex)
    {
        // Do something...
    }
    

    使用您当前的代码,您可能会遇到一些其他类型的异常,这是您没有预料到的。目前你只会忽略这个异常,甚至不会记录它。这会使调试正在发生的事情变得非常困难。如果您有无法处理的异常,您应该重新抛出它或记录它。

    我想捕获所有异常

    如果您真的想要这样做,那么您可以编写如下代码:

    catch (SocketTimeoutException ex)
    {
        // Do something specific for SocketTimeoutException.
    }
    catch (Exception ex)
    {
        // Do something for all other types of exception.
    }
    

    关于您的具体错误,您写道:

    !a.equals(b) || !a.equals(c)
    

    此表达式的计算结果始终为真。你的意思是:

    !a.equals(b) && !a.equals(c)
    

    或等效:

    !(a.equals(b) || a.equals(c))
    

    请注意,通过按照我上面的建议重写您的代码,您可以完全避免编写这个复杂的布尔表达式。

    【讨论】:

    • 注意:您还可以添加一个 rethrows the exception 的 else 块,但如果无法阻止仅捕获您需要捕获的异常,这应该是最后的手段
    • 我想捕获所有异常(甚至是我忘记的异常),这就是为什么我将这段代码留在其中,因为它处于非常远的 alpha 阶段,我不知道会发生什么。我正在尝试忽略 SocketTimeOutException 和其他......但我希望完全支持任何错过的异常
    • SSpoke 如果这是在测试的早期阶段,您根本不应该捕获任何异常,因为您希望立即查看每个可能的故障点
    • @SSpoke:如果你真的想要这样做,你可以在其他 catch 块之后添加一个 catch (Exception ex) 块。但是不要在没有记录的情况下吞下异常——这是你能做的最糟糕的事情。
    • 这是一个服务器,如果它发生故障,它可能会跳出线程并完全搞砸。因此,内置异常以打破内部循环等。就像在等待完整数据包到达时,连接可能会丢失,所以我抛出自定义异常超时作为内置行为
    【解决方案2】:

    依靠异常消息来了解异常的原因确实不安全。

    在您的情况下,您可以尝试捕获更具体的异常,例如 SocketTimeoutException 和经典的 IOException

    void func() {
        try {
            //socket disconnects in middle of ..parsing packet..
        } catch(SocketTimeoutException ex) {
            //In case of Time out
        } catch(IOException ex){
            //For other IOExceptions
        }
    }
    

    来源:

    [Socket.connect()][3]

    即使您更喜欢在异常消息中查找信息,您也不应该检查消息是否简单地等于“超时”,而是检查消息是否包含“超时”

    [3]:http://download-llnw.oracle.com/javase/6/docs/api/java/net/Socket.html#connect(java.net.SocketAddress,整数)

    【讨论】:

    • 好吧,我理解了一点.. 所以你说我应该在上面添加大量的 blank 捕获异常.. 这将作为避免条件。和没有条件的最终捕获(异常前)?如果某些异常没有用,请尝试找出它是什么并将其也添加到空白中?问题是.. 它会在 24 小时内在我的 CentOS 服务器中生成日志,这些日志非常大(200 mb),我只想保留我以前从未见过的新异常用于修复目的
    • 不,我是说你应该捕获你需要获取日志的 IOException 并将它们分开处理,然后你可以捕获所有其他异常并记录所有内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    相关资源
    最近更新 更多