首页 > 解决方案 > 使用 Omnifaces 在 JSF 中处理 Ajax 请求的异常:始终显示状态代码 200 而不是 500

问题描述

我们目前正在向我们的 JSF Web 应用程序添加一个监控解决方案 (Dynatrace)。监控解决方案检查指示错误的状态代码以标记用户会话中的问题。我们正在尝试使用 Omnifaces FullAjaxExceptionHander(参见http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler)来处理 Ajax 异常并呈现错误页面。正如您从屏幕截图中看到的,Omnifaces 设置错误代码为 500,但 POST 上的状态代码在 Chrome 中显示为 200。由于 Dynatrace 没有看到错误状态代码,因此它不会在用户会话中对此进行标记。

知道为什么没有在响应中设置状态码吗?我以为我看到它在我们系统的 POST 上短暂显示了 500 的状态代码,但现在它只再次显示 200。那时我尝试了 Omnifaces 展示中的示例,但我只得到了 200 个。

浏览器收到的 Omnifaces Showcase 和状态码的屏幕截图

标签: jsfomnifacesdynatrace

解决方案


这是因为它在技术上是一个成功的Ajax响应。即,它已成功地将错误页面内容作为<partial-response>Ajax 响应 XML 正文的一部分传递。

如果 Ajax 响应的状态为 500,则 JSF 根本不会解析 Ajax 响应 XML,而是调用处理程序,该onerror处理程序反过来触发任何已注册的自定义客户端代码。这是事情变得复杂的地方,因为它默认不渲染任何东西,而FullAjaxExceptionHandler真正想要利用现有的 JSF Ajax 渲染逻辑。

最好的办法是检查您的监控服务是否提供基于 Java 的 API 来手动通知错误情况。如果是这样,则覆盖其中一种FullAjaxExceptionHandler方法来对其进行 ping 操作。是一个很好的shouldHandleExceptionRootCause()候选人。如有必要,您还可以在此处instanceof检查异常以跳过某些异常。

我对 Dynatrace 不熟悉,但如果您使用的是NewRelic,它会是这样的:

import com.newrelic.api.agent.NewRelic;

public class CustomExceptionHandler extends FullAjaxExceptionHandler {

    @Override
    protected boolean shouldHandleExceptionRootCause(FacesContext context, Throwable exception) {
        try {
            NewRelic.noticeError(exception);
        }
        catch (Exception e) {
            // Log a WARN line
        }

        return true;
    }
}

最后为它创建一个自定义ExceptionHandlerFactory并用它替换FullAjaxExceptionHandlerFactoryin faces-config.xml


推荐阅读