I would like to create an exception for subscribers if the code is something other than 0. How is this possible using Retrofit and Rx?
You can use the Observable.flatMap operator:
api.request().flatMap(response -> { if (response.getCode() != 0) { return Observable.error(new Exception("Remote error occurred")); } return Observable.just(response); });
I would prefer to write this logic only once and apply it to all observables returned by modification.
Unfortunately, there is no way to do this using retrofit and rx-java . You have to write the code above for each retrofit call. The only thing you can do is use the Observable.compose method and reduce the number of templates you really need to write.
api.request().compose(new ResponseTransformer<Response>());
And here is the ResponseTransformer class:
public static class ResponseTransformer<T extends Response> implements Observable.Transformer<T, T> { @Override public Observable<T> call(final Observable<T> observable) { return observable.flatMap(response -> { if (response.getCode() != 0) { return Observable.error(new Exception("Remote error occurred")); } return Observable.just(response); }); } }
UPDATE
Well, as I said, there is no way to avoid the template code using only retrofit and rxjava , but you can bypass it using dynamic proxies (note that you no longer need to call compose ):
final Api api = restAdapter.create(Api.class); final ClassLoader loader = api.getClass().getClassLoader(); final Class<?>[] interfaces = api.getClass().getInterfaces(); final Api proxy = (Api) Proxy.newProxyInstance(loader, interfaces, new ResponseInvocationHandler(api)); proxy.request().subscribe(response -> { System.out.println("Success!"); });
ResponseInvocationHandler class:
public static class ResponseInvocationHandler implements InvocationHandler { private final Object target; public ResponseInvocationHandler(final Object target) { this.target = target; } @Override @SuppressWarnings({"unchecked"}) public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { final Object result = method.invoke(target, args); if (result instanceof Observable) { return Observable.class.cast(result).compose(new ResponseTransformer<>()); } return result; } }