正确打印servlet异常的stacktrace

发布于 2024-07-19 15:55:28 字数 359 浏览 4 评论 0原文

我使用过滤器来捕获 servlet 异常(因为我们使用的是 jsf/plain servlet 的混合),

因此,当捕获 ServletException 并调用 printstacktrace 时,

大部分信息都会丢失。 “真正的”根异常似乎隐藏在“有趣的”表达后面,

((ServletException) e.getRootCause().getCause()).getRootCause().getCause().getCause().getCause()

这显然不是这样做的方法。

是打印此类异常的“完整”信息的简单方法。 有人可以解释一下为什么异常是这样包装的吗?

so i am using a filter to catch servlet exception (because we are using a mix of jsf/plain servlets)

when catching the ServletException and calling printstacktrace most of the information is lost.

the "true" root exception seems to be hidden behind the "funny" expression

((ServletException) e.getRootCause().getCause()).getRootCause().getCause().getCause().getCause()

this is clearly not the way to do it.

is the an easy way to print the "full" information of such an exception.
can someone explain me why the exception is wrapped this way?

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

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

发布评论

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

评论(4

故人爱我别走 2024-07-26 15:55:28

Take a look at the ExceptionUtils class from commons-lang. It contains several useful methods for printing the entire chain of exceptions.

街角迷惘 2024-07-26 15:55:28

在我查看了 ExceptionUtils 之后,这解决了问题!

    final StringWriter stacktrace = new StringWriter();
    ExceptionUtils.printRootCauseStackTrace(throwable,new PrintWriter(stacktrace));
    msg.append(stacktrace.getBuffer());

这会打印出包含每条相关信息的完整堆栈跟踪。

after i had a look at ExceptionUtils, this solved the problem!

    final StringWriter stacktrace = new StringWriter();
    ExceptionUtils.printRootCauseStackTrace(throwable,new PrintWriter(stacktrace));
    msg.append(stacktrace.getBuffer());

this prints out the full stacktrace with every piece of information that is relevant.

淡莣 2024-07-26 15:55:28

这称为异常链接。 通过将异常包装在不同的异常中,您可以让异常在堆栈中向上冒泡,而无需主应用程序类担心某些低级异常。

示例:

public void doStuff() throws StuffException {
    try {
        doDatabaseStuff();
    } catch (DatabaseException de1) {
        throw new StuffException("Could not do stuff in the database.", de1);
    }
}

这样您的应用程序只需处理 StuffException,但如果确实需要,它可以获取底层 DatabaseException

要找到您捕获的异常的最底层(以及所有其他)异常,您可以迭代其根本原因:

    ...
} catch (SomeException se1) {
    Throwable t = se1;
    logger.log(Level.WARNING, "Top exception", se1);
    while (t.getCause() != null) {
        t = t.getCause();
        logger.log(Level.WARNING, "Nested exception", t);
    }
    // now t contains the root cause
}

That is called exception chaining. By wrapping an exception in a different exception you can let exceptions bubble up the stack without having your main application classes to worry about some low-level exceptions.

Example:

public void doStuff() throws StuffException {
    try {
        doDatabaseStuff();
    } catch (DatabaseException de1) {
        throw new StuffException("Could not do stuff in the database.", de1);
    }
}

This way your application only has to handle StuffException but it can get to the underlying DatabaseException if it really needs to.

To get to the bottom-most (and all other) exception(s) of an exception you caught you can iterator over its root causes:

    ...
} catch (SomeException se1) {
    Throwable t = se1;
    logger.log(Level.WARNING, "Top exception", se1);
    while (t.getCause() != null) {
        t = t.getCause();
        logger.log(Level.WARNING, "Nested exception", t);
    }
    // now t contains the root cause
}
无所的.畏惧 2024-07-26 15:55:28

ServletException 的异常链接很棘手。 根据所使用的 Web 服务器实现和 Web 开发框架,运行时链可能会使用 Cause 和/或 rootCause。 这个链接很好地解释了这一点。 让事情变得复杂的是,我见过一些异常,其中原因指向异常本身。
这是我们使用的递归方法,涵盖了 ServletExceptions 的所有基础:

public static Throwable getDeepCause(Throwable ex) {
    if (ex == null) {
        return ex;
    }
    Throwable cause;
    if (ex instanceof ServletException) {
        cause = ((ServletException) ex).getRootCause();
        if (cause == null) {
            cause = ex.getCause();
        }
    } else {
        cause = ex.getCause();
    }
    if (cause != null && cause != ex) {
        return getDeepCause(cause);
    } else {
        // stop condition - reached the end of the exception chain
        return ex;
    }
}

Exception chaining for ServletException is tricky. Depending on the web server implementation and web development framework in use, at runtime the chain may use cause and/or rootCause. This link explains it very well. To complicate things, I've seen exceptions where the cause points to the exception itself.
Here's a recursive method we have used that covers all bases for ServletExceptions:

public static Throwable getDeepCause(Throwable ex) {
    if (ex == null) {
        return ex;
    }
    Throwable cause;
    if (ex instanceof ServletException) {
        cause = ((ServletException) ex).getRootCause();
        if (cause == null) {
            cause = ex.getCause();
        }
    } else {
        cause = ex.getCause();
    }
    if (cause != null && cause != ex) {
        return getDeepCause(cause);
    } else {
        // stop condition - reached the end of the exception chain
        return ex;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文