4

从 catch 块中抛出异常只是为了记录消息以便我们确定导致异常的原因是否有意义?

代码

  public void saveLogs(Logs logs) throws RemoteException
  {
        try
        {
            LogsOps.saveLogs(logs);
        }
        catch (RemoteException e)
        {
            log.info("RemoteException is thrown while trying to save logs ", e);
            throw new RemoteException("RemoteException caused while trying to save", e);
        }
    }

为了响应下面的评论之一,该方法会抛出 StackOverFlow 异常,这里是 log.info 的实际实现,它只显示这些错误。

     /** Log the message and the exception with a level of INFO.
     * @param message - The message text.
     * @param t - An exception to display.
     */
    public void info(Object message, Throwable t)
    {
        String nullSafeMessage = (message != null) ? message.toString() : t.getClass().getSimpleName();
        log.info(nullSafeMessage, t);
    }

所以永远不会抛出 Stackoverflow 异常。

4

3 回答 3

10

这取决于将要捕获更高级别的异常。如果没有其他东西会记录该消息,那么当然,这是有道理的——尽管我可能会重新抛出原始异常而不是创建一个新异常:

catch (RemoteException e)
{
    log.info("RemoteException is thrown while trying to save logs ", e);
    throw e;
}

但是,理想情况下,您应该catch在堆栈更高的位置有一个块,它会适当地记录 - 如果您只是记录异常,那么无论如何都可以获得所有信息。

当您想要记录异常中不存在的信息(例如参数值)时,捕获/记录/重新抛出可能是有意义的。

于 2012-12-11T14:51:19.590 回答
3

假设您最终将处理传播的异常,这种 catch-log-rethrow 策略只会弄乱日志文件。想象一下,这是在堆栈跟踪的整个过程中完成的——你最终会得到大量没有用处的冗余错误信息。

如果你不处理异常,你也不应该记录它。

于 2012-12-11T14:51:48.783 回答
0

除了用于日志记录之外,这种方法还可用于在失败的情况下执行必要的清理,然后再将控制权返回给堆栈中的调用者。

例如

InputStream is = new InputStream( ... )

try {

    is.read(...);

    return is;

} catch ( IOException ioe ) {
    is.close();
    throw ioe;
}

当然,这是一种有点特殊的用法,大多数情况下可以通过使用finally子句优雅地避免 - 但并非总是如此,如上面的例子所示。

于 2012-12-11T15:01:16.420 回答