Accessing doc id from exception 'handler' with 2.0 SDK

I’m trying to get a better understanding of how to use the new Observable features in the 2.0 Java SDK.

From the documentation…

The following example will only go to the replica if a TimeoutException happened (if not the error is passed down):

bucket
.get("id")
.timeout(500, TimeUnit.MILLISECONDS)
.onErrorResumeNext(new Func1<Throwable, Observable<? extends JsonDocument>>() {
    @Override
    public Observable<? extends JsonDocument> call(Throwable throwable) {
        if (throwable instanceof TimeoutException) {
            return bucket.getFromReplica("id", ReplicaMode.ALL);
        }
        return Observable.error(throwable);
    }
});

In the call(Throwable throwable) function, i’d like to be able to access the id of the JsonDocument for which this TimeoutException was thrown – so that a getFromReplica can be issued.

My difficulty is that as I’m new to this style of programming, I can’t quite see how to access the JsonDocument at this point, or how it could be passed down so that it was accessible from the call(Throwable throwable) function.

Cheers,
Tom

Hi,

there are a few ways, but let me point out two of them:

The first one is simpler - but not so “pure”, because you are leaking state. Let’s say you have a method wrapped for a transparent get functionality, you already have the ID in scope and can just reuse it, basically like:

public static Observable<JsonDocument> getWithFallback(final String id) {
    return Observable
        .just(id)
        .flatMap(new Func1<String, Observable<JsonDocument>>() {
            @Override
            public Observable<JsonDocument> call(String id) {
                return bucket.async().get(id);
            }
        })
        .onErrorResumeNext(bucket.async().getFromReplica(id, ReplicaMode.ALL))
        .first()
        .timeout(500, TimeUnit.MILLISECONDS);
}

If you want to be more pure and not share the ID, or maybe sometimes you just don’t have access to it from the outside, you can just ned inside a flatmap:

public static Observable<JsonDocument> getWithFallback(final String id) {
    return Observable
        .just(id)
        .flatMap(new Func1<String, Observable<JsonDocument>>() {
            @Override
            public Observable<JsonDocument> call(String innerId) {
                return bucket
                    .async().get(innerId)
                    .onErrorResumeNext(bucket.async().getFromReplica(innerId, ReplicaMode.ALL))
                    .first();
            }
        })
        .timeout(500, TimeUnit.MILLISECONDS);
}