我们当前正在向我们的JSF Web应用程序添加监视解决方案(Dynatrace)。监视解决方案检查指示错误的状态码,以标记用户会话中的问题。我们正在尝试使用Omnifaces FullAjaxExceptionHander(请参见http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler)来处理Ajax异常并呈现错误页面。从屏幕截图中可以看到,Omnifaces的错误代码设置为500,但POST上的状态代码在Chrome中显示为200。由于Dynatrace看不到错误状态代码,因此不会在用户会话上对此进行标记。
知道为什么未在响应中设置状态代码吗?我以为我看到它在我们的系统中的POST上简短地给出了状态代码500,但是现在只显示200。那是我在Omnifaces展示柜上尝试该示例时遇到的问题,我只得到200个很好的示例。
这是因为从技术上来说,这是成功的Ajax响应。即它已经成功地将错误页面内容作为Ajax响应XML主体中<partial-response>
的一部分进行了传递。
如果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
,并用它替换FullAjaxExceptionHandlerFactory
中的faces-config.xml
。