/**
  * Construct a <code>ElasticsearchException</code> with the specified detail message and nested
  * exception.
  *
  * <p>The message can be parameterized using <code>{}</code> as placeholders for the given
  * arguments
  *
  * @param msg the detail message
  * @param cause the nested exception
  * @param args the arguments for the message
  */
 public ElasticsearchException(String msg, Throwable cause, Object... args) {
   super(LoggerMessageFormat.format(msg, args), cause);
 }
    private void perform(@Nullable final Throwable currentFailure) {
      Throwable lastFailure = this.lastFailure;
      if (lastFailure == null || TransportActions.isReadOverrideException(currentFailure)) {
        lastFailure = currentFailure;
        this.lastFailure = currentFailure;
      }
      final ShardRouting shardRouting = shardIt.nextOrNull();
      if (shardRouting == null) {
        Throwable failure = lastFailure;
        if (failure == null || isShardNotAvailableException(failure)) {
          failure =
              new NoShardAvailableActionException(
                  null,
                  LoggerMessageFormat.format(
                      "No shard available for [{}]", internalRequest.request()),
                  failure);
        } else {
          if (logger.isDebugEnabled()) {
            logger.debug("{}: failed to execute [{}]", failure, null, internalRequest.request());
          }
        }
        listener.onFailure(failure);
        return;
      }
      DiscoveryNode node = nodes.get(shardRouting.currentNodeId());
      if (node == null) {
        onFailure(shardRouting, new NoShardAvailableActionException(shardRouting.shardId()));
      } else {
        internalRequest.request().internalShardId = shardRouting.shardId();
        if (logger.isTraceEnabled()) {
          logger.trace(
              "sending request [{}] to shard [{}] on node [{}]",
              internalRequest.request(),
              internalRequest.request().internalShardId,
              node);
        }
        transportService.sendRequest(
            node,
            transportShardAction,
            internalRequest.request(),
            new BaseTransportResponseHandler<Response>() {

              @Override
              public Response newInstance() {
                return newResponse();
              }

              @Override
              public String executor() {
                return ThreadPool.Names.SAME;
              }

              @Override
              public void handleResponse(final Response response) {
                listener.onResponse(response);
              }

              @Override
              public void handleException(TransportException exp) {
                onFailure(shardRouting, exp);
              }
            });
      }
    }
 /**
  * Construct a <code>ElasticsearchException</code> with the specified detail message.
  *
  * <p>The message can be parameterized using <code>{}</code> as placeholders for the given
  * arguments
  *
  * @param msg the detail message
  * @param args the arguments for the message
  */
 public ElasticsearchException(String msg, Object... args) {
   super(LoggerMessageFormat.format(msg, args));
 }