docs: public HandleErrorResult primaryFail(Method method, Object[] args, boolean killCmd) {
      boolean alreadyClosed = masterProtocol == null || !masterProtocol.isConnected();
      boolean inTransaction = masterProtocol != null && masterProtocol.inTransaction();
  
      //in case of SocketTimeoutException due to having set socketTimeout, must force connection close
      if (masterProtocol != null && masterProtocol.isConnected()) {
        masterProtocol.close();
      }
  
      //fail on slave if parameter permit so
      if (urlParser.getOptions().failOnReadOnly && !isSecondaryHostFail()) {
        try {
          if (this.secondaryProtocol != null && this.secondaryProtocol.ping()) {
            //switching to secondary connection
            proxy.lock.lock();
            try {
              if (masterProtocol != null) {
                syncConnection(masterProtocol, this.secondaryProtocol);
              }
              currentProtocol = this.secondaryProtocol;
            } finally {
              proxy.lock.unlock();
            }
            FailoverLoop.addListener(this);
            try {
              return relaunchOperation(method, args);
            } catch (Exception e) {
              //relaunchOperation failed
            }
            return new HandleErrorResult();
          }
        } catch (Exception e) {
          if (setSecondaryHostFail()) {
            blackListAndCloseConnection(this.secondaryProtocol);
          }
        }
      }
  
      try {
        reconnectFailedConnection(new SearchFilter(true, urlParser.getOptions().failOnReadOnly));
        handleFailLoop();
        if (currentProtocol != null) {
          if (killCmd) {
            return new HandleErrorResult(true, false);
          }
  
          if (currentReadOnlyAsked || alreadyClosed || !inTransaction && isQueryRelaunchable(method,
              args)) {
            //connection was not in transaction
  
            //can relaunch query
            logger.info("Connection to master lost, new master {}, conn={} found"
                    + ", query type permit to be re-execute on new server without throwing exception",
                currentProtocol.getHostAddress(),
                currentProtocol.getServerThreadId());
            return relaunchOperation(method, args);
          }
          //throw Exception because must inform client, even if connection is reconnected
          return new HandleErrorResult(true);
        } else {
          setMasterHostFail();
          FailoverLoop.removeListener(this);
          return new HandleErrorResult();
        }
      } catch (Exception e) {
        //we will throw a Connection exception that will close connection
        if (e.getCause() != null
            && proxy.hasToHandleFailover((SQLException) e.getCause())
            && currentProtocol != null
            && currentProtocol.isConnected()) {
          currentProtocol.close();
        }
        setMasterHostFail();
        FailoverLoop.removeListener(this);
        return new HandleErrorResult();
      }
    }