转发过程中 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
当我的 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