# API inconsistency with ActionListener

**URL:** <https://discuss.elastic.co/t/api-inconsistency-with-actionlistener/11886>\
**Category:** Elasticsearch\
**Created:** [May 8, 2013, 10:31pm UTC](https://discuss.elastic.co/t/api-inconsistency-with-actionlistener/11886 "2013-05-08T22:31:13Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Blake\_Smith](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/blake_smith/32/2346_2.png) [@Blake\_Smith](https://discuss.elastic.co/u/Blake_Smith)\
**Post date:** [May 8, 2013, 10:31pm UTC](https://discuss.elastic.co/t/api-inconsistency-with-actionlistener/11886/1 "2013-05-08T22:31:13Z")

</div>

Hey there!

I was hoping someone can shed some light on a possible ES Java client API  
inconsistency.

In my current project (in Scala using Twitter Finagle), we're wrapping the  
ES Java client so we can expose all client actions via twitter Futures  
([http://twitter.github.io/util/util-core/target/doc/main/api/com/twitter/util/Future.html](http://twitter.github.io/util/util-core/target/doc/main/api/com/twitter/util/Future.html))

We wrap our calls to ES in a Promise, and provide an overridden  
ActionListener like so:

private def magnet[Request \<: ActionRequest[Request], Response \<:  
ActionResponse, RequestBuilder \<: ActionRequestBuilder[Request, Response,  
RequestBuilder]](action: Action[Request, Response, RequestBuilder]):  
ActionMagnet[Request, Response] =  
new ActionMagnet[Request, Response] {  
def execute(javaClient: Client, request: Request) = {  
val promise = new Promise[Response]  
javaClient.execute(action, request, actionListener(promise))  
promise  
}  
}

private def actionListener[A](promise: Promise[A]) = new  
ActionListener[A] {  
def onResponse(response: A) {  
promise.setValue(response)  
}

```
def onFailure(e: Throwable) {
  promise.setException(e)
}

```

}

Everything works great for successful responses: onResponse is getting  
called and the promise value is getting delivered. When exceptions are  
thrown, onFailure is never called, so exceptions bubble out of the client  
call forcing us to wrap them in try / catch blocks.

I'm confused about the seeming inconsistency in this API. Digging into the  
ES source, I found I would have to make the following change to get the  
ActionListener onFailure invokation I wanted:

## diff --git a/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java b/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java index 9cbd9f5..2e44262 100644

a/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java  
+++  
b/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java  
@@ -199,7 +199,8 @@ public class TransportClientNodesService extends  
AbstractComponent {  
public void execute(NodeListenerCallback  
callback, ActionListener listener) throws ElasticSearchException {  
ImmutableList nodes = this.nodes;  
if (nodes.isEmpty()) {

- 

```
       throw new NoNodeAvailableException();

```

- 

```
       listener.onFailure(new NoNodeAvailableException());

```

- 

```
       return;
   }
   int index = randomNodeGenerator.incrementAndGet();
   if (index < 0) {

```

@@ -213,7 +214,7 @@ public class TransportClientNodesService extends  
AbstractComponent {  
if (e.unwrapCause() instanceof ConnectTransportException) {  
retryListener.onFailure(e);  
} else {

- 

```
           throw e;

```

- 

```
           listener.onFailure(e);
       }
   }

```

}

Can someone help me get my thinking straight about the ActionListener API?  
When is onFailure supposed to be invoked?

Thanks, I'm loving ES so far!

Blake Smith

--  
You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 6, 2017, 2:37am UTC](https://discuss.elastic.co/t/api-inconsistency-with-actionlistener/11886/2 "2017-07-06T02:37:29Z")

</div>


