This is an automated email from the ASF dual-hosted git repository.

xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 6475ba2  [type: refactor] optimize fallback logic. (#2732)
6475ba2 is described below

commit 6475ba29da14bb808116e4d813c9608ef72fb665
Author: Qicz <[email protected]>
AuthorDate: Sun Jan 9 21:46:46 2022 +0800

    [type: refactor] optimize fallback logic. (#2732)
    
    * [type: refactor] optimize fallback logic.
    
    * polish
    
    * polish
    
    * add fallback test
---
 .../src/main/resources/application.yml             |  2 +
 .../apache/shenyu/common/config/ShenyuConfig.java  | 68 ++++++++++++++-
 .../shenyu/plugin/api/result/ShenyuResult.java     |  4 +-
 .../shenyu/plugin/api/result/ShenyuResultEnum.java |  5 ++
 .../shenyu/plugin/api/result/ShenyuResultWrap.java | 17 ++--
 .../shenyu/plugin/cryptor/utils/CryptorUtil.java   |  4 +-
 .../apache/shenyu/plugin/divide/DividePlugin.java  |  8 +-
 .../alibaba/dubbo/AlibabaDubboPluginTest.java      |  2 +-
 .../plugin/dubbo/common/AbstractDubboPlugin.java   |  4 +-
 .../org/apache/shenyu/plugin/grpc/GrpcPlugin.java  |  6 +-
 .../plugin/httpclient/NettyHttpClientPlugin.java   |  2 +-
 .../shenyu/plugin/httpclient/WebClientPlugin.java  |  2 +-
 .../shenyu/plugin/hystrix/command/Command.java     |  8 +-
 .../org/apache/shenyu/plugin/jwt/JwtPlugin.java    |  4 +-
 .../apache/shenyu/plugin/motan/MotanPlugin.java    |  4 +-
 .../plugin/ratelimiter/RateLimiterPlugin.java      |  2 +-
 .../plugin/resilience4j/executor/Executor.java     | 10 +--
 .../plugin/response/strategy/RPCMessageWriter.java |  3 +-
 .../response/strategy/WebClientMessageWriter.java  |  4 +-
 .../sentinel/fallback/SentinelFallbackHandler.java |  6 +-
 .../org/apache/shenyu/plugin/sofa/SofaPlugin.java  |  4 +-
 .../plugin/springcloud/SpringCloudPlugin.java      |  6 +-
 .../org/apache/shenyu/plugin/tars/TarsPlugin.java  |  6 +-
 .../shenyu/plugin/websocket/WebSocketPlugin.java   |  2 +-
 .../starter/gateway/ShenyuConfiguration.java       | 16 +++-
 .../web/fallback/DefaultFallbackController.java    | 61 --------------
 .../apache/shenyu/web/filter/FallbackFilter.java   | 96 ++++++++++++++++++++++
 .../apache/shenyu/web/filter/FileSizeFilter.java   |  2 +-
 .../fallback/DefaultFallbackControllerTest.java    | 77 -----------------
 .../shenyu/web/filter/FallbackFilterTest.java      | 77 +++++++++++++++++
 30 files changed, 320 insertions(+), 192 deletions(-)

diff --git a/shenyu-bootstrap/src/main/resources/application.yml 
b/shenyu-bootstrap/src/main/resources/application.yml
index 8bbd201..b9a517f 100644
--- a/shenyu-bootstrap/src/main/resources/application.yml
+++ b/shenyu-bootstrap/src/main/resources/application.yml
@@ -132,6 +132,8 @@ shenyu:
     enabled: false
     paths:
       - /favicon.ico
+  fallback:
+    enabled: true
   extPlugin:
     path:
     enabled: true
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java 
b/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
index 981c7d1..9b5947f 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
@@ -37,6 +37,8 @@ public class ShenyuConfig {
     private FileConfig file = new FileConfig();
     
     private ExcludePath exclude = new ExcludePath();
+
+    private FallbackPath fallback = new FallbackPath();
     
     private ExtPlugin extPlugin = new ExtPlugin();
     
@@ -155,7 +157,25 @@ public class ShenyuConfig {
     public void setExclude(final ExcludePath exclude) {
         this.exclude = exclude;
     }
-    
+
+    /**
+     * Gets fallback.
+     *
+     * @return the fallback
+     */
+    public FallbackPath getFallback() {
+        return fallback;
+    }
+
+    /**
+     * Sets fallback.
+     *
+     * @param fallback the fallback
+     */
+    public void setFallback(final FallbackPath fallback) {
+        this.fallback = fallback;
+    }
+
     /**
      * Gets upstream check.
      *
@@ -411,6 +431,52 @@ public class ShenyuConfig {
             return paths;
         }
     }
+
+    /**
+     * The type fallback path.
+     */
+    public static class FallbackPath {
+
+        private Boolean enabled = false;
+
+        private List<String> paths = new ArrayList<>();
+
+        /**
+         * Gets enabled.
+         *
+         * @return the enabled
+         */
+        public Boolean getEnabled() {
+            return enabled;
+        }
+
+        /**
+         * Sets enabled.
+         *
+         * @param enabled the enabled
+         */
+        public void setEnabled(final Boolean enabled) {
+            this.enabled = enabled;
+        }
+
+        /**
+         * Sets paths.
+         *
+         * @param paths the paths
+         */
+        public void setPaths(final List<String> paths) {
+            this.paths = paths;
+        }
+
+        /**
+         * get paths.
+         *
+         * @return paths paths
+         */
+        public List<String> getPaths() {
+            return paths;
+        }
+    }
     
     /**
      * The type File config.
diff --git 
a/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResult.java
 
b/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResult.java
index bd66073..b4a54dc 100644
--- 
a/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResult.java
+++ 
b/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResult.java
@@ -94,5 +94,7 @@ public interface ShenyuResult<T> {
      * @param object  the object
      * @return the t
      */
-    T error(int code, String message, Object object);
+    default T error(int code, String message, Object object) {
+        return null;
+    }
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultEnum.java
 
b/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultEnum.java
index edc5460..fdf543e 100644
--- 
a/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultEnum.java
+++ 
b/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultEnum.java
@@ -63,6 +63,11 @@ public enum ShenyuResultEnum {
     RESILIENCE4J_PLUGIN_FALLBACK(429, "Resilience4JPlugin fallback success, 
please check your service status!"),
 
     /**
+     * the default fallback, due to a circuit break.
+     */
+    DEFAULT_FALLBACK(429, "the fallback success, please check your service 
status!"),
+
+    /**
      * Meta data error shenyu result enum.
      */
     META_DATA_ERROR(430, "Meta data error!"),
diff --git 
a/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultWrap.java
 
b/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultWrap.java
index 08a35be..1c5c813 100644
--- 
a/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultWrap.java
+++ 
b/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultWrap.java
@@ -20,8 +20,6 @@ package org.apache.shenyu.plugin.api.result;
 import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
 import org.springframework.web.server.ServerWebExchange;
 
-import java.util.Objects;
-
 /**
  * The type shenyu result warp.
  */
@@ -45,15 +43,24 @@ public final class ShenyuResultWrap {
      * Error object.
      *
      * @param exchange the exchange
+     * @param shenyuResult    the shenyuResult
+     * @param object  the object
+     * @return the object
+     */
+    public static Object error(final ServerWebExchange exchange, final 
ShenyuResultEnum shenyuResult, final Object object) {
+        return shenyuResult().error(exchange, shenyuResult.getCode(), 
shenyuResult.getMsg(), object);
+    }
+
+    /**
+     * Error object.
+     *
+     * @param exchange the exchange
      * @param code    the code
      * @param message the message
      * @param object  the object
      * @return the object
      */
     public static Object error(final ServerWebExchange exchange, final int 
code, final String message, final Object object) {
-        if (Objects.isNull(exchange)) {
-            return shenyuResult().error(code, message, object);
-        }
         return shenyuResult().error(exchange, code, message, object);
     }
 
diff --git 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/CryptorUtil.java
 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/CryptorUtil.java
index f9e0633..26ff5eb 100644
--- 
a/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/CryptorUtil.java
+++ 
b/shenyu-plugin/shenyu-plugin-cryptor/src/main/java/org/apache/shenyu/plugin/cryptor/utils/CryptorUtil.java
@@ -47,8 +47,8 @@ public final class CryptorUtil {
     public static Mono<Void> fail(final String mode, final ServerWebExchange 
exchange) {
         Object error = Optional.ofNullable(mode)
                 .filter(CryptorStrategyFactory.DECRYPT::equals)
-                .map(mod -> ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.DECRYPTION_ERROR.getCode(), 
ShenyuResultEnum.DECRYPTION_ERROR.getMsg(), null))
-                .orElse(ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.ENCRYPTION_ERROR.getCode(), 
ShenyuResultEnum.ENCRYPTION_ERROR.getMsg(), null));
+                .map(mod -> ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.DECRYPTION_ERROR, null))
+                .orElse(ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.ENCRYPTION_ERROR, null));
         return WebFluxResultUtils.result(exchange, error);
     }
 
diff --git 
a/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
 
b/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
index bbbaaab..4f5e420 100644
--- 
a/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
@@ -65,25 +65,25 @@ public class DividePlugin extends AbstractShenyuPlugin {
         }
         if (headerSize > ruleHandle.getHeaderMaxSize()) {
             LOG.error("request header is too large");
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.REQUEST_HEADER_TOO_LARGE.getCode(), 
ShenyuResultEnum.REQUEST_HEADER_TOO_LARGE.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.REQUEST_HEADER_TOO_LARGE, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         if (exchange.getRequest().getHeaders().getContentLength() > 
ruleHandle.getRequestMaxSize()) {
             LOG.error("request entity is too large");
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.REQUEST_ENTITY_TOO_LARGE.getCode(), 
ShenyuResultEnum.REQUEST_ENTITY_TOO_LARGE.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.REQUEST_ENTITY_TOO_LARGE, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         List<Upstream> upstreamList = 
UpstreamCacheManager.getInstance().findUpstreamListBySelectorId(selector.getId());
         if (CollectionUtils.isEmpty(upstreamList)) {
             LOG.error("divide upstream configuration error: {}", rule);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL.getCode(), 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         String ip = 
Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress();
         Upstream upstream = LoadBalancerFactory.selector(upstreamList, 
ruleHandle.getLoadBalance(), ip);
         if (Objects.isNull(upstream)) {
             LOG.error("divide has no upstream");
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL.getCode(), 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         // set the http url
diff --git 
a/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-alibaba-dubbo/src/test/java/org/apache/shenyu/plugin/alibaba/dubbo/AlibabaDubboPluginTest.java
 
b/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-alibaba-dubbo/src/test/java/org/apache/shenyu/plugin/alibaba/dubbo/AlibabaDubboPluginTest.java
index dccc465..10adc0a 100644
--- 
a/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-alibaba-dubbo/src/test/java/org/apache/shenyu/plugin/alibaba/dubbo/AlibabaDubboPluginTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-alibaba-dubbo/src/test/java/org/apache/shenyu/plugin/alibaba/dubbo/AlibabaDubboPluginTest.java
@@ -133,7 +133,7 @@ public final class AlibabaDubboPluginTest {
 
         try (MockedStatic<ShenyuResultWrap> shenyuResultWrapMockedStatic = 
mockStatic(ShenyuResultWrap.class)) {
             shenyuResultWrapMockedStatic.when(() -> ShenyuResultWrap
-                    .error(exchange, 
ShenyuResultEnum.DUBBO_HAVE_BODY_PARAM.getCode(), 
ShenyuResultEnum.DUBBO_HAVE_BODY_PARAM.getMsg(), null))
+                    .error(exchange, ShenyuResultEnum.DUBBO_HAVE_BODY_PARAM, 
null))
                     .thenReturn(new Object());
 
             Mono<Void> voidMono = 
alibabaDubboPluginUnderTest.doExecute(exchange, chain, selectorData, data);
diff --git 
a/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-dubbo-common/src/main/java/org/apache/shenyu/plugin/dubbo/common/AbstractDubboPlugin.java
 
b/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-dubbo-common/src/main/java/org/apache/shenyu/plugin/dubbo/common/AbstractDubboPlugin.java
index db2807b..98dc648 100644
--- 
a/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-dubbo-common/src/main/java/org/apache/shenyu/plugin/dubbo/common/AbstractDubboPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-dubbo/shenyu-plugin-dubbo-common/src/main/java/org/apache/shenyu/plugin/dubbo/common/AbstractDubboPlugin.java
@@ -92,12 +92,12 @@ public abstract class AbstractDubboPlugin extends 
AbstractShenyuPlugin {
         if (!checkMetaData(metaData)) {
             LOG.error(" path is : {}, meta data have error : {}", 
shenyuContext.getPath(), metaData);
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.META_DATA_ERROR.getCode(), 
ShenyuResultEnum.META_DATA_ERROR.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.META_DATA_ERROR, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         if (Objects.nonNull(metaData) && 
StringUtils.isNoneBlank(metaData.getParameterTypes()) && 
StringUtils.isBlank(param)) {
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.DUBBO_HAVE_BODY_PARAM.getCode(), 
ShenyuResultEnum.DUBBO_HAVE_BODY_PARAM.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.DUBBO_HAVE_BODY_PARAM, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         this.rpcContext(exchange);
diff --git 
a/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/GrpcPlugin.java
 
b/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/GrpcPlugin.java
index 83b4e26..c714be6 100644
--- 
a/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/GrpcPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/GrpcPlugin.java
@@ -70,20 +70,20 @@ public class GrpcPlugin extends AbstractShenyuPlugin {
         if (!checkMetaData(metaData)) {
             LOG.error(" path is :{}, meta data have error.... {}", 
shenyuContext.getPath(), metaData);
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.META_DATA_ERROR.getCode(), 
ShenyuResultEnum.META_DATA_ERROR.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.META_DATA_ERROR, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         assert metaData != null;
         if (StringUtils.isNoneBlank(metaData.getParameterTypes()) && 
StringUtils.isBlank(param)) {
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.GRPC_HAVE_BODY_PARAM.getCode(), 
ShenyuResultEnum.GRPC_HAVE_BODY_PARAM.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.GRPC_HAVE_BODY_PARAM, null);
             return WebFluxResultUtils.result(exchange, error);
         }
 
         final ShenyuGrpcClient client = 
GrpcClientCache.getGrpcClient(selector.getName());
         if (Objects.isNull(client)) {
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.GRPC_CLIENT_NULL.getCode(), 
ShenyuResultEnum.GRPC_CLIENT_NULL.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.GRPC_CLIENT_NULL, null);
             return WebFluxResultUtils.result(exchange, error);
         }
 
diff --git 
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
 
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
index 472fdb1..81c223a 100644
--- 
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
@@ -88,7 +88,7 @@ public class NettyHttpClientPlugin implements ShenyuPlugin {
         }
         URI uri = exchange.getAttribute(Constants.HTTP_URI);
         if (Objects.isNull(uri)) {
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_URL.getCode(), 
ShenyuResultEnum.CANNOT_FIND_URL.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_URL, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         LOG.info("you request, The resulting urlPath is: {}", 
uri.toASCIIString());
diff --git 
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
 
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
index 3c9423a..24e8fc3 100644
--- 
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
@@ -72,7 +72,7 @@ public class WebClientPlugin implements ShenyuPlugin {
         assert shenyuContext != null;
         URI uri = exchange.getAttribute(Constants.HTTP_URI);
         if (Objects.isNull(uri)) {
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_URL.getCode(), 
ShenyuResultEnum.CANNOT_FIND_URL.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_URL, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         long timeout = (long) 
Optional.ofNullable(exchange.getAttribute(Constants.HTTP_TIME_OUT)).orElse(3000L);
diff --git 
a/shenyu-plugin/shenyu-plugin-hystrix/src/main/java/org/apache/shenyu/plugin/hystrix/command/Command.java
 
b/shenyu-plugin/shenyu-plugin-hystrix/src/main/java/org/apache/shenyu/plugin/hystrix/command/Command.java
index ef120c3..526f0bf 100644
--- 
a/shenyu-plugin/shenyu-plugin-hystrix/src/main/java/org/apache/shenyu/plugin/hystrix/command/Command.java
+++ 
b/shenyu-plugin/shenyu-plugin-hystrix/src/main/java/org/apache/shenyu/plugin/hystrix/command/Command.java
@@ -65,17 +65,17 @@ public interface Command {
             HystrixRuntimeException e = (HystrixRuntimeException) exception;
             if (e.getFailureType() == 
HystrixRuntimeException.FailureType.TIMEOUT) {
                 
exchange.getResponse().setStatusCode(HttpStatus.GATEWAY_TIMEOUT);
-                error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_TIMEOUT.getCode(), 
ShenyuResultEnum.SERVICE_TIMEOUT.getMsg(), null);
+                error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_TIMEOUT, null);
             } else {
                 
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-                error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getCode(), 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
+                error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR, null);
             }
         } else if (exception instanceof HystrixTimeoutException) {
             exchange.getResponse().setStatusCode(HttpStatus.GATEWAY_TIMEOUT);
-            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_TIMEOUT.getCode(), 
ShenyuResultEnum.SERVICE_TIMEOUT.getMsg(), null);
+            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_TIMEOUT, null);
         } else {
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getCode(), 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
+            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR, null);
         }
         return error;
     }
diff --git 
a/shenyu-plugin/shenyu-plugin-jwt/src/main/java/org/apache/shenyu/plugin/jwt/JwtPlugin.java
 
b/shenyu-plugin/shenyu-plugin-jwt/src/main/java/org/apache/shenyu/plugin/jwt/JwtPlugin.java
index 3b599b0..5c8c0d5 100644
--- 
a/shenyu-plugin/shenyu-plugin-jwt/src/main/java/org/apache/shenyu/plugin/jwt/JwtPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-jwt/src/main/java/org/apache/shenyu/plugin/jwt/JwtPlugin.java
@@ -60,7 +60,7 @@ public class JwtPlugin extends AbstractShenyuPlugin {
 
         // check secreteKey
         if (StringUtils.isEmpty(jwtConfig.getSecretKey())) {
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SECRET_KEY_MUST_BE_CONFIGURED.getCode(), 
ShenyuResultEnum.SECRET_KEY_MUST_BE_CONFIGURED.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SECRET_KEY_MUST_BE_CONFIGURED, null);
             return WebFluxResultUtils.result(exchange, error);
         }
 
@@ -74,7 +74,7 @@ public class JwtPlugin extends AbstractShenyuPlugin {
             }
             return chain.execute(converter(exchange, jwtBody, 
ruleHandle.getConverter()));
         }
-        Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.ERROR_TOKEN.getCode(), ShenyuResultEnum.ERROR_TOKEN.getMsg(), 
null);
+        Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.ERROR_TOKEN, null);
         return WebFluxResultUtils.result(exchange, error);
     }
 
diff --git 
a/shenyu-plugin/shenyu-plugin-motan/src/main/java/org/apache/shenyu/plugin/motan/MotanPlugin.java
 
b/shenyu-plugin/shenyu-plugin-motan/src/main/java/org/apache/shenyu/plugin/motan/MotanPlugin.java
index 64fecf4..99fd9f2 100644
--- 
a/shenyu-plugin/shenyu-plugin-motan/src/main/java/org/apache/shenyu/plugin/motan/MotanPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-motan/src/main/java/org/apache/shenyu/plugin/motan/MotanPlugin.java
@@ -69,12 +69,12 @@ public class MotanPlugin extends AbstractShenyuPlugin {
             assert metaData != null;
             LOG.error("path is :{}, meta data have error.... {}", 
shenyuContext.getPath(), metaData);
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.META_DATA_ERROR.getCode(), 
ShenyuResultEnum.META_DATA_ERROR.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.META_DATA_ERROR, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         if (StringUtils.isNoneBlank(metaData.getParameterTypes()) && 
StringUtils.isBlank(param)) {
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.MOTAN_HAVE_BODY_PARAM.getCode(), 
ShenyuResultEnum.MOTAN_HAVE_BODY_PARAM.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.MOTAN_HAVE_BODY_PARAM, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         final Mono<Object> result = motanProxyService.genericInvoker(param, 
metaData, exchange);
diff --git 
a/shenyu-plugin/shenyu-plugin-ratelimiter/src/main/java/org/apache/shenyu/plugin/ratelimiter/RateLimiterPlugin.java
 
b/shenyu-plugin/shenyu-plugin-ratelimiter/src/main/java/org/apache/shenyu/plugin/ratelimiter/RateLimiterPlugin.java
index 44140c4..c7e2158 100644
--- 
a/shenyu-plugin/shenyu-plugin-ratelimiter/src/main/java/org/apache/shenyu/plugin/ratelimiter/RateLimiterPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-ratelimiter/src/main/java/org/apache/shenyu/plugin/ratelimiter/RateLimiterPlugin.java
@@ -73,7 +73,7 @@ public class RateLimiterPlugin extends AbstractShenyuPlugin {
                 .flatMap(response -> {
                     if (!response.isAllowed()) {
                         
exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
-                        Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.TOO_MANY_REQUESTS.getCode(), 
ShenyuResultEnum.TOO_MANY_REQUESTS.getMsg(), null);
+                        Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.TOO_MANY_REQUESTS, null);
                         return WebFluxResultUtils.result(exchange, error);
                     }
                     return chain.execute(exchange);
diff --git 
a/shenyu-plugin/shenyu-plugin-resilience4j/src/main/java/org/apache/shenyu/plugin/resilience4j/executor/Executor.java
 
b/shenyu-plugin/shenyu-plugin-resilience4j/src/main/java/org/apache/shenyu/plugin/resilience4j/executor/Executor.java
index 21002ab..e5ef2e4 100644
--- 
a/shenyu-plugin/shenyu-plugin-resilience4j/src/main/java/org/apache/shenyu/plugin/resilience4j/executor/Executor.java
+++ 
b/shenyu-plugin/shenyu-plugin-resilience4j/src/main/java/org/apache/shenyu/plugin/resilience4j/executor/Executor.java
@@ -82,18 +82,18 @@ public interface Executor {
         Object error;
         if (throwable instanceof TimeoutException) {
             exchange.getResponse().setStatusCode(HttpStatus.GATEWAY_TIMEOUT);
-            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_TIMEOUT.getCode(), 
ShenyuResultEnum.SERVICE_TIMEOUT.getMsg(), null);
+            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_TIMEOUT, null);
         } else if (throwable instanceof 
Resilience4JPlugin.CircuitBreakerStatusCodeException) {
             return Mono.error(throwable);
         } else if (throwable instanceof CallNotPermittedException) {
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getCode(), 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
+            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR, null);
         } else if (throwable instanceof RequestNotPermitted) {
             exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
-            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.TOO_MANY_REQUESTS.getCode(), 
ShenyuResultEnum.TOO_MANY_REQUESTS.getMsg(), null);
+            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.TOO_MANY_REQUESTS, null);
         } else {
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getCode(), 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
+            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR, null);
         }
         return WebFluxResultUtils.result(exchange, error);
     }
@@ -106,7 +106,7 @@ public interface Executor {
      */
     default Mono<Void> error(ServerWebExchange exchange) {
         exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-        Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getCode(), 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
+        Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR, null);
         return WebFluxResultUtils.result(exchange, error);
     }
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/RPCMessageWriter.java
 
b/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/RPCMessageWriter.java
index 17d3d2b..46d226f 100644
--- 
a/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/RPCMessageWriter.java
+++ 
b/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/RPCMessageWriter.java
@@ -37,8 +37,7 @@ public class RPCMessageWriter implements MessageWriter {
         return chain.execute(exchange).then(Mono.defer(() -> {
             Object result = exchange.getAttribute(Constants.RPC_RESULT);
             if (Objects.isNull(result)) {
-                Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getCode(),
-                        ShenyuResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
+                Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR, null);
                 return WebFluxResultUtils.result(exchange, error);
             }
             return WebFluxResultUtils.result(exchange, result);
diff --git 
a/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/WebClientMessageWriter.java
 
b/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/WebClientMessageWriter.java
index 21e133a..313296e 100644
--- 
a/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/WebClientMessageWriter.java
+++ 
b/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/WebClientMessageWriter.java
@@ -53,11 +53,11 @@ public class WebClientMessageWriter implements 
MessageWriter {
             if (Objects.isNull(clientResponse)
                     || response.getStatusCode() == HttpStatus.BAD_GATEWAY
                     || response.getStatusCode() == 
HttpStatus.INTERNAL_SERVER_ERROR) {
-                Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getCode(), 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
+                Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR, null);
                 return WebFluxResultUtils.result(exchange, error);
             }
             if (response.getStatusCode() == HttpStatus.GATEWAY_TIMEOUT) {
-                Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_TIMEOUT.getCode(), 
ShenyuResultEnum.SERVICE_TIMEOUT.getMsg(), null);
+                Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_TIMEOUT, null);
                 return WebFluxResultUtils.result(exchange, error);
             }
             response.getCookies().putAll(clientResponse.cookies());
diff --git 
a/shenyu-plugin/shenyu-plugin-sentinel/src/main/java/org/apache/shenyu/plugin/sentinel/fallback/SentinelFallbackHandler.java
 
b/shenyu-plugin/shenyu-plugin-sentinel/src/main/java/org/apache/shenyu/plugin/sentinel/fallback/SentinelFallbackHandler.java
index 0f00f62..29cdaa5 100644
--- 
a/shenyu-plugin/shenyu-plugin-sentinel/src/main/java/org/apache/shenyu/plugin/sentinel/fallback/SentinelFallbackHandler.java
+++ 
b/shenyu-plugin/shenyu-plugin-sentinel/src/main/java/org/apache/shenyu/plugin/sentinel/fallback/SentinelFallbackHandler.java
@@ -38,13 +38,13 @@ public class SentinelFallbackHandler implements 
FallbackHandler {
         Object error;
         if (throwable instanceof DegradeException) {
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getCode(), 
ShenyuResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
+            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SERVICE_RESULT_ERROR, null);
         } else if (throwable instanceof FlowException) {
             exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
-            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.TOO_MANY_REQUESTS.getCode(), 
ShenyuResultEnum.TOO_MANY_REQUESTS.getMsg(), null);
+            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.TOO_MANY_REQUESTS, null);
         } else if (throwable instanceof BlockException) {
             exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
-            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SENTINEL_BLOCK_ERROR.getCode(), 
ShenyuResultEnum.SENTINEL_BLOCK_ERROR.getMsg(), null);
+            error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SENTINEL_BLOCK_ERROR, null);
         } else {
             return Mono.error(throwable);
         }
diff --git 
a/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/SofaPlugin.java
 
b/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/SofaPlugin.java
index af56e91..48c2a82 100644
--- 
a/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/SofaPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/SofaPlugin.java
@@ -69,12 +69,12 @@ public class SofaPlugin extends AbstractShenyuPlugin {
             assert metaData != null;
             LOG.error(" path is :{}, meta data have error.... {}", 
shenyuContext.getPath(), metaData);
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.META_DATA_ERROR.getCode(), 
ShenyuResultEnum.META_DATA_ERROR.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.META_DATA_ERROR, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         if (StringUtils.isNoneBlank(metaData.getParameterTypes()) && 
StringUtils.isBlank(param)) {
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SOFA_HAVE_BODY_PARAM.getCode(), 
ShenyuResultEnum.SOFA_HAVE_BODY_PARAM.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.SOFA_HAVE_BODY_PARAM, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         Map<String, Map<String, String>> rpcContext = 
exchange.getAttribute(Constants.GENERAL_CONTEXT);
diff --git 
a/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/SpringCloudPlugin.java
 
b/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/SpringCloudPlugin.java
index 5e68c09..bed6401 100644
--- 
a/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/SpringCloudPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/SpringCloudPlugin.java
@@ -72,8 +72,7 @@ public class SpringCloudPlugin extends AbstractShenyuPlugin {
         String serviceId = springCloudSelectorHandle.getServiceId();
         if (StringUtils.isBlank(serviceId)) {
             Object error = ShenyuResultWrap.error(exchange,
-                    
ShenyuResultEnum.CANNOT_CONFIG_SPRINGCLOUD_SERVICEID.getCode(),
-                    
ShenyuResultEnum.CANNOT_CONFIG_SPRINGCLOUD_SERVICEID.getMsg(), null);
+                    ShenyuResultEnum.CANNOT_CONFIG_SPRINGCLOUD_SERVICEID, 
null);
             return WebFluxResultUtils.result(exchange, error);
         }
         String ip = 
Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress();
@@ -87,8 +86,7 @@ public class SpringCloudPlugin extends AbstractShenyuPlugin {
         }
         if (Objects.isNull(serviceInstance)) {
             Object error = ShenyuResultWrap.error(exchange,
-                    ShenyuResultEnum.SPRINGCLOUD_SERVICEID_IS_ERROR.getCode(),
-                    ShenyuResultEnum.SPRINGCLOUD_SERVICEID_IS_ERROR.getMsg(), 
null);
+                    ShenyuResultEnum.SPRINGCLOUD_SERVICEID_IS_ERROR, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         URI uri = loadBalancer.reconstructURI(serviceInstance, 
URI.create(shenyuContext.getRealUrl()));
diff --git 
a/shenyu-plugin/shenyu-plugin-tars/src/main/java/org/apache/shenyu/plugin/tars/TarsPlugin.java
 
b/shenyu-plugin/shenyu-plugin-tars/src/main/java/org/apache/shenyu/plugin/tars/TarsPlugin.java
index 7634f9c..be54faf 100644
--- 
a/shenyu-plugin/shenyu-plugin-tars/src/main/java/org/apache/shenyu/plugin/tars/TarsPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-tars/src/main/java/org/apache/shenyu/plugin/tars/TarsPlugin.java
@@ -66,12 +66,12 @@ public class TarsPlugin extends AbstractShenyuPlugin {
             assert metaData != null;
             LOG.error(" path is :{}, meta data have error.... {}", 
shenyuContext.getPath(), metaData);
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.META_DATA_ERROR.getCode(), 
ShenyuResultEnum.META_DATA_ERROR.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.META_DATA_ERROR, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         if (StringUtils.isNoneBlank(metaData.getParameterTypes()) && 
StringUtils.isBlank(body)) {
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.TARS_HAVE_BODY_PARAM.getCode(), 
ShenyuResultEnum.TARS_HAVE_BODY_PARAM.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.TARS_HAVE_BODY_PARAM, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         TarsInvokePrxList tarsInvokePrxList = 
ApplicationConfigCache.getInstance().get(metaData.getPath());
@@ -85,7 +85,7 @@ public class TarsPlugin extends AbstractShenyuPlugin {
         } catch (Exception e) {
             LOG.error("Invoke tars error", e);
             
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.TARS_INVOKE.getCode(), ShenyuResultEnum.TARS_INVOKE.getMsg(), 
null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.TARS_INVOKE, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         return Mono.fromFuture(future.thenApply(ret -> {
diff --git 
a/shenyu-plugin/shenyu-plugin-websocket/src/main/java/org/apache/shenyu/plugin/websocket/WebSocketPlugin.java
 
b/shenyu-plugin/shenyu-plugin-websocket/src/main/java/org/apache/shenyu/plugin/websocket/WebSocketPlugin.java
index 1642bec..966d243 100644
--- 
a/shenyu-plugin/shenyu-plugin-websocket/src/main/java/org/apache/shenyu/plugin/websocket/WebSocketPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-websocket/src/main/java/org/apache/shenyu/plugin/websocket/WebSocketPlugin.java
@@ -93,7 +93,7 @@ public class WebSocketPlugin extends AbstractShenyuPlugin {
         Upstream upstream = LoadBalancerFactory.selector(upstreamList, 
ruleHandle.getLoadBalance(), ip);
         if (Objects.isNull(upstream)) {
             LOG.error("websocket has no upstream");
-            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL.getCode(), 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL.getMsg(), null);
+            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.CANNOT_FIND_HEALTHY_UPSTREAM_URL, null);
             return WebFluxResultUtils.result(exchange, error);
         }
         URI wsRequestUrl = 
UriComponentsBuilder.fromUri(URI.create(buildWsRealPath(upstream, 
shenyuContext))).build().toUri();
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/main/java/org/apache/shenyu/springboot/starter/gateway/ShenyuConfiguration.java
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/main/java/org/apache/shenyu/springboot/starter/gateway/ShenyuConfiguration.java
index 8fcf408..b16c178 100644
--- 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/main/java/org/apache/shenyu/springboot/starter/gateway/ShenyuConfiguration.java
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/src/main/java/org/apache/shenyu/springboot/starter/gateway/ShenyuConfiguration.java
@@ -29,6 +29,7 @@ import 
org.apache.shenyu.web.configuration.ShenyuExtConfiguration;
 import org.apache.shenyu.web.configuration.SpringExtConfiguration;
 import org.apache.shenyu.web.filter.CrossFilter;
 import org.apache.shenyu.web.filter.ExcludeFilter;
+import org.apache.shenyu.web.filter.FallbackFilter;
 import org.apache.shenyu.web.filter.FileSizeFilter;
 import org.apache.shenyu.web.filter.LocalDispatcherFilter;
 import org.apache.shenyu.web.forward.ForwardedRemoteAddressResolver;
@@ -198,7 +199,20 @@ public class ShenyuConfiguration {
     public WebFilter excludeFilter(final ShenyuConfig shenyuConfig) {
         return new ExcludeFilter(shenyuConfig.getExclude().getPaths());
     }
-    
+
+    /**
+     * fallback filter web filter.
+     *
+     * @param shenyuConfig the shenyu config
+     * @return the fallback web filter
+     */
+    @Bean
+    @Order(-5)
+    @ConditionalOnProperty(name = "shenyu.fallback.enabled", havingValue = 
"true")
+    public WebFilter fallbackFilter(final ShenyuConfig shenyuConfig) {
+        return new FallbackFilter(shenyuConfig.getFallback().getPaths());
+    }
+
     /**
      * shenyu config.
      *
diff --git 
a/shenyu-web/src/main/java/org/apache/shenyu/web/fallback/DefaultFallbackController.java
 
b/shenyu-web/src/main/java/org/apache/shenyu/web/fallback/DefaultFallbackController.java
deleted file mode 100644
index 499be30..0000000
--- 
a/shenyu-web/src/main/java/org/apache/shenyu/web/fallback/DefaultFallbackController.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shenyu.web.fallback;
-
-import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
-import org.apache.shenyu.plugin.api.result.ShenyuResultWrap;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * The default fallback for hystrix plugin and resilience4j plugin.
- */
-@RestController
-@RequestMapping(value = "/fallback", produces = 
{MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
-public class DefaultFallbackController {
-    /**
-     * logger.
-     */
-    private static final Logger LOG = 
LoggerFactory.getLogger(DefaultFallbackController.class);
-
-    /**
-     * default fallback for hystrix.
-     *
-     * @return the shenyu result
-     */
-    @GetMapping("/hystrix")
-    public Object hystrixPluginFallback() {
-        LOG.error("the default fallback for hystrix");
-        return ShenyuResultWrap.error(null, 
ShenyuResultEnum.HYSTRIX_PLUGIN_FALLBACK.getCode(), 
ShenyuResultEnum.HYSTRIX_PLUGIN_FALLBACK.getMsg(), null);
-    }
-
-    /**
-     * default fallback for resilience4j.
-     *
-     * @return the shenyu result
-     */
-    @GetMapping("/resilience4j")
-    public Object resilience4jFallBack() {
-        LOG.error("the default fallback for resilience4j");
-        return ShenyuResultWrap.error(null, 
ShenyuResultEnum.RESILIENCE4J_PLUGIN_FALLBACK.getCode(), 
ShenyuResultEnum.RESILIENCE4J_PLUGIN_FALLBACK.getMsg(), null);
-    }
-}
diff --git 
a/shenyu-web/src/main/java/org/apache/shenyu/web/filter/FallbackFilter.java 
b/shenyu-web/src/main/java/org/apache/shenyu/web/filter/FallbackFilter.java
new file mode 100644
index 0000000..20dd653
--- /dev/null
+++ b/shenyu-web/src/main/java/org/apache/shenyu/web/filter/FallbackFilter.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.web.filter;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
+import org.apache.shenyu.plugin.api.result.ShenyuResultWrap;
+import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.lang.NonNull;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+import reactor.core.publisher.Mono;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * FallbackFilter.
+ */
+public class FallbackFilter implements WebFilter {
+
+    /**
+     * logger.
+     */
+    private static final Logger LOG = 
LoggerFactory.getLogger(FallbackFilter.class);
+
+    private static final AntPathMatcher MATCHER = new AntPathMatcher();
+
+    private static final String HYSTRIX = "/fallback/hystrix";
+
+    private static final String RESILIENCE4J = "/fallback/resilience4j";
+
+    private final Set<String> paths;
+
+    public FallbackFilter(final List<String> paths) {
+        if (CollectionUtils.isNotEmpty(paths)) {
+            this.paths = new HashSet<>(paths);
+        } else {
+            this.paths = new HashSet<>();
+        }
+        this.paths.add(HYSTRIX);
+        this.paths.add(RESILIENCE4J);
+    }
+
+    @Override
+    @NonNull
+    public Mono<Void> filter(@NonNull final ServerWebExchange exchange, 
@NonNull final WebFilterChain chain) {
+        ServerHttpRequest request = exchange.getRequest();
+        String path = request.getURI().getPath();
+        Set<String> fallbackPaths = Collections.unmodifiableSet(this.paths);
+        boolean match = fallbackPaths.stream().anyMatch(url -> reg(url, path));
+        if (match) {
+            Object error = this.getError(exchange, path);
+            return WebFluxResultUtils.result(exchange, error);
+        }
+        return chain.filter(exchange);
+    }
+
+    private static boolean reg(final String pattern, final String path) {
+        return MATCHER.match(pattern, path);
+    }
+
+    private Object getError(final ServerWebExchange exchange, final String 
path) {
+        if (HYSTRIX.equals(path)) {
+            LOG.error("the fallback for hystrix");
+            return ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.HYSTRIX_PLUGIN_FALLBACK, null);
+        }
+        if (RESILIENCE4J.equals(path)) {
+            LOG.error("the fallback for resilience4j");
+            return ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.RESILIENCE4J_PLUGIN_FALLBACK, null);
+        }
+        return ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.DEFAULT_FALLBACK, null);
+    }
+}
diff --git 
a/shenyu-web/src/main/java/org/apache/shenyu/web/filter/FileSizeFilter.java 
b/shenyu-web/src/main/java/org/apache/shenyu/web/filter/FileSizeFilter.java
index 8fa75b9..3b22e3b 100644
--- a/shenyu-web/src/main/java/org/apache/shenyu/web/filter/FileSizeFilter.java
+++ b/shenyu-web/src/main/java/org/apache/shenyu/web/filter/FileSizeFilter.java
@@ -73,7 +73,7 @@ public class FileSizeFilter implements WebFilter {
                         if (size.capacity() > BYTES_PER_MB * fileMaxSize) {
                             ServerHttpResponse response = 
exchange.getResponse();
                             response.setStatusCode(HttpStatus.BAD_REQUEST);
-                            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.PAYLOAD_TOO_LARGE.getCode(), 
ShenyuResultEnum.PAYLOAD_TOO_LARGE.getMsg(), null);
+                            Object error = ShenyuResultWrap.error(exchange, 
ShenyuResultEnum.PAYLOAD_TOO_LARGE, null);
                             return WebFluxResultUtils.result(exchange, error);
                         }
                         BodyInserter<Mono<DataBuffer>, 
ReactiveHttpOutputMessage> bodyInsert = 
BodyInserters.fromPublisher(Mono.just(size), DataBuffer.class);
diff --git 
a/shenyu-web/src/test/java/org/apache/shenyu/web/fallback/DefaultFallbackControllerTest.java
 
b/shenyu-web/src/test/java/org/apache/shenyu/web/fallback/DefaultFallbackControllerTest.java
deleted file mode 100644
index 0afc722..0000000
--- 
a/shenyu-web/src/test/java/org/apache/shenyu/web/fallback/DefaultFallbackControllerTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shenyu.web.fallback;
-
-import org.apache.shenyu.plugin.api.result.DefaultShenyuResult;
-import org.apache.shenyu.plugin.api.result.ShenyuResult;
-import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
-import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.junit.MockitoJUnitRunner;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-
-import static org.hamcrest.core.Is.is;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static 
org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static 
org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-/**
- * Test case for DefaultFallbackController.
- */
-@RunWith(MockitoJUnitRunner.class)
-public final class DefaultFallbackControllerTest {
-
-    private MockMvc mockMvc;
-
-    @InjectMocks
-    private DefaultFallbackController defaultFallbackController;
-
-    @Before
-    public void setUp() {
-        ConfigurableApplicationContext context = 
mock(ConfigurableApplicationContext.class);
-        SpringBeanUtils.getInstance().setApplicationContext(context);
-        when(context.getBean(ShenyuResult.class)).thenReturn(new 
DefaultShenyuResult() { });
-
-        this.mockMvc = 
MockMvcBuilders.standaloneSetup(defaultFallbackController).build();
-    }
-
-    @Test
-    public void testFallback() throws Exception {
-        this.mockMvc.perform(MockMvcRequestBuilders.get("/fallback/hystrix"))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.code", 
is(ShenyuResultEnum.HYSTRIX_PLUGIN_FALLBACK.getCode())))
-                .andExpect(jsonPath("$.message", 
is(ShenyuResultEnum.HYSTRIX_PLUGIN_FALLBACK.getMsg())))
-                .andReturn();
-    }
-
-    @Test
-    public void testResilience4jFallback() throws Exception {
-        
this.mockMvc.perform(MockMvcRequestBuilders.get("/fallback/resilience4j"))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.code", 
is(ShenyuResultEnum.RESILIENCE4J_PLUGIN_FALLBACK.getCode())))
-                .andExpect(jsonPath("$.message", 
is(ShenyuResultEnum.RESILIENCE4J_PLUGIN_FALLBACK.getMsg())))
-                .andReturn();
-    }
-}
diff --git 
a/shenyu-web/src/test/java/org/apache/shenyu/web/filter/FallbackFilterTest.java 
b/shenyu-web/src/test/java/org/apache/shenyu/web/filter/FallbackFilterTest.java
new file mode 100644
index 0000000..0d3707f
--- /dev/null
+++ 
b/shenyu-web/src/test/java/org/apache/shenyu/web/filter/FallbackFilterTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.web.filter;
+
+import org.apache.shenyu.plugin.api.result.ShenyuResult;
+import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
+import org.springframework.mock.web.server.MockServerWebExchange;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilterChain;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.Silent.class)
+public final class FallbackFilterTest {
+    
+    private FallbackFilter fallbackFilter;
+
+    private WebFilterChain webFilterChain;
+
+    @Before
+    public void setUp() {
+        ConfigurableApplicationContext context = 
mock(ConfigurableApplicationContext.class);
+        SpringBeanUtils.getInstance().setApplicationContext(context);
+        
when(context.getBean(ShenyuResult.class)).thenReturn(mock(ShenyuResult.class));
+        List<String> paths = new ArrayList<>();
+        paths.add("/fallback/hystrix");
+        fallbackFilter = new FallbackFilter(paths);
+        webFilterChain = mock(WebFilterChain.class);
+        when(webFilterChain.filter(any())).thenReturn(Mono.empty());
+    }
+
+    @Test
+    public void testFilterMatch() {
+        ServerWebExchange webExchange =
+                MockServerWebExchange.from(MockServerHttpRequest
+                        .post("http://localhost:8080/fallback/hystrix";));
+        Mono<Void> filter = fallbackFilter.filter(webExchange, webFilterChain);
+        StepVerifier.create(filter).expectSubscription().verifyComplete();
+    }
+
+    @Test
+    public void testFilterNotMatch() {
+        ServerWebExchange webExchange =
+                MockServerWebExchange.from(MockServerHttpRequest
+                        .post("http://localhost:8080/";));
+        Mono<Void> filter = fallbackFilter.filter(webExchange, webFilterChain);
+        StepVerifier.create(filter).expectSubscription().verifyComplete();
+    }
+}

Reply via email to