转发过程中 Zuul SendErrorFilter 出错

Error in Zuul SendErrorFilter during forward

当我的 Zuul 过滤器无法路由到已配置的 URL 时,'RibbonRoutingFilter' class 抛出一个 ZuulException 说 "Forwarding error" 并且控制转到 'SendErrorFilter' class.

现在,当 SendErrorFilter class 尝试进行转发时,在此转发调用期间发生另一个异常。

dispatcher.forward(ctx.getRequest(), ctx.getResponse());

在此转发调用期间发生的异常是

Caused by: java.lang.IllegalArgumentException: UT010023: Request org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter$Servlet30RequestWrapper@6dc974ea was not original or a wrapper
    at io.undertow.servlet.spec.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:103) ~[undertow-servlet-1.1.3.Final.jar:1.1.3.Final]
    at org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter.run(SendErrorFilter.java:74) ~[spring-cloud-netflix-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
    at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112) ~[zuul-core-1.0.28.jar:na]
    at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:197) ~[zuul-core-1.0.28.jar:na]

最后,当控件到达我的自定义 ZuulErrorFilter 时,我没有得到原来的异常。相反,我得到的异常对象是在转发期间发生的异常对象。

更新: 我发现可以将 errorPath 属性 配置为指向错误处理服务。如果未配置,Zuul 默认会查找名为 /error 的服务并尝试发送到该服务。由于我们没有为 /error 提供任何服务,因此 dispatcher.forward() 抛出错误。

问题 我们怎样才能跳过这个 fwd 到错误处理服务?我们有一个 ErrorFilter 来记录错误。我们不希望有错误处理服务。

我们遇到了同样的问题,有一个简单的解决方案可以修复 Undertow "eating" 原始异常,关注我的博客 post:

http://blog.jmnarloch.io/2015/09/16/spring-cloud-zuul-error-handling/

您需要将标志 allow-non-standard-wrappers 设置为 true。在 Spring Boot 中,这可以通过注册自定义 UndertowDeploymentInfoCustomizer 来实现。示例:

@Bean
public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
    UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
    factory.addDeploymentInfoCustomizers(new UndertowDeploymentInfoCustomizer() {
        @Override
        public void customize(DeploymentInfo deploymentInfo) {
            deploymentInfo.setAllowNonStandardWrappers(true);
        }
    });
    return factory;
}

现在关于这个问题,无论哪种方式,我都强烈建议您实现自己的 ErrorController,否则您可能会遇到奇怪的 Spring 引导行为(在我们的设置中 - 默认设置总是生成 Whitelabel带有 200 HTTP 状态代码的错误页面 - 这在 Tomcat 上从未发生过矛盾)并且这种方式不能被 AJAX 调用消耗。

相关 Github 问题:https://github.com/spring-cloud/spring-cloud-netflix/issues/524