在catch块中重新抛出异常是否有意义?

时间:2012-12-11 14:48:24

标签: java exception

从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 Exception,这里只是显示那些错误的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异常。

3 个答案:

答案 0 :(得分:10)

这取决于什么会在更高的范围内捕获异常。如果没有 else 将要记录消息,那么确定,这是有道理的 - 虽然我可能会重新抛出原始异常而不是创建一个新异常:

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

理想情况下,您在堆栈上方有一个catch块,可以正确记录 - 如果您只是记录异常,那么可以获得所有信息无论如何。

当你想记录异常中的信息时,可能有意义捕获/记录/重新抛出,例如参数值。

答案 1 :(得分:3)

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

如果您没有处理异常,则不应该记录它。

答案 2 :(得分:0)

除了日志记录之外,这种方法还可用于在发生故障之前执行必要的清理,然后再将控制权返回到堆栈中的调用者。

例如

InputStream is = new InputStream( ... )

try {

    is.read(...);

    return is;

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

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