We are working on a dubbo gateway and need to support mutual access between different network clusters. This should be a common scenario. This requires dubbo to do two things for us:

1. Dynamically modify the ip and change the access of the local cluster to remote. This extension can be done, although there are some bugs, https://dubbo.apache.org/zh/docs3-v2/java-sdk/advanced-features-and-usage/service/specify-ip/

2. Forward the dubbo request. When the gateway receives the access request from cluster A, it should forward it to cluster B (now it returns an exception).

  From the code execution process.
  current:
  gateway-dubbo-provider receives the request -> parses -> judges whether the request interface has a corresponding cache URL -> no -> throws IOException -> netty returns

  ```java
  void handleRequest(final ExchangeChannel channel, Request req) throws RemotingException {
          Response res = new Response(req.getId(), req.getVersion());
          if (req.isBroken()) {
              Object data = req.getData();
              String msg;
              if (data == null) {
                  msg = null;
              } else if (data instanceof Throwable) {
                  msg = StringUtils.toString((Throwable) data);
              } else {
                  msg = data.toString();
              }
              res.setErrorMessage("Fail to decode request due to: " + msg);
              res.setStatus(Response.BAD_REQUEST);

              channel.send(res);
              return;
          }
  }
  ```

  ​

  expect:
  gateway-dubbo-provider receives the request -> parses -> judges whether the request interface has a corresponding cache URL -> no -> obtains the exception handler through spi (the request can be forwarded here) -> netty returns

```java
  void handleRequest(final ExchangeChannel channel, Request req) throws RemotingException {
          Response res = new Response(req.getId(), req.getVersion());
          if (req.isBroken()) {
              Object data = req.getData();
           //expert begin
          List<ExceptionHandler> list = spiExtensions.listByType(ExceptionHandler); 
          list.forEach(handler.handle(path,version))
           //expert end
              String msg;
              if (data == null) {
                  msg = null;
              } else if (data instanceof Throwable) {
                  msg = StringUtils.toString((Throwable) data);
              } else {
                  msg = data.toString();
              }
              res.setErrorMessage("Fail to decode request due to: " + msg);
              res.setStatus(Response.BAD_REQUEST);

              channel.send(res);
              return;
          }
  }
```


Since dubbo.extension provides dynamic ip replacement, then we should consider whether the target ip can be accepted and processed. I think this exception handler is an extension function of the dubbo.extension package.
We can provide ExceptionHandler similar to springboot, which can be more flexible

String CLASS_DESERIALIZE_ALLOWED_LIST = "dubbo.security.serialize.allowedClassList";
    String CLASS_DESERIALIZE_BLOCKED_LIST = "dubbo.security.serialize.blockedClassList";
    String ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE = "dubbo.security.serialize.generic.native-java-enable";
    String SERIALIZE_BLOCKED_LIST_FILE_PATH = "security/serialize.blockedlist";
    String SERIALIZE_ALLOW_LIST_FILE_PATH = "security/serialize.allowlist";
    String SERIALIZE_CHECK_STATUS_KEY = "dubbo.application.serialize-check-status";
    String QOS_LIVE_PROBE_EXTENSION = "dubbo.application.liveness-probe";
    String QOS_READY_PROBE_EXTENSION = "dubbo.application.readiness-probe";
    String QOS_STARTUP_PROBE_EXTENSION = "dubbo.application.startup-probe";
    String REGISTRY_DELAY_NOTIFICATION_KEY = "delay-notification";
    String CACHE_CLEAR_TASK_INTERVAL = "dubbo.application.url.cache.task.interval";
    String CACHE_CLEAR_WAITING_THRESHOLD = "dubbo.application.url.cache.clear.waiting";
    String CLUSTER_INTERCEPTOR_COMPATIBLE_KEY = "dubbo.application.cluster.interceptor.compatible";
    String UTF8ENCODE = "UTF-8";
    /**
     * Pseudo URL prefix for loading from the class path: "classpath:".
     */
    String CLASSPATH_URL_PREFIX = "classpath:";
    String DEFAULT_VERSION = "0.0.0";
    String CLASS_DESERIALIZE_OPEN_CHECK = "dubbo.security.serialize.openCheckClass";
    String ROUTER_KEY = "router";
    String EXPORT_ASYNC_KEY = "export-async";
    String REFER_ASYNC_KEY = "refer-async";
    String EXPORT_BACKGROUND_KEY = "export-background";
    String REFER_BACKGROUND_KEY = "refer-background";
    String EXPORT_THREAD_NUM_KEY = "export-thread-num";
    String REFER_THREAD_NUM_KEY = "refer-thread-num";
    int DEFAULT_EXPORT_THREAD_NUM = 10;
    int DEFAULT_REFER_THREAD_NUM = 10;
    int DEFAULT_DELAY_NOTIFICATION_TIME = 5000;