Retrofit 2 + RxAndroid: Handle Errors (4xx and some 200)

人走茶凉 提交于 2020-01-13 14:56:13

问题


I saw a lot of articles and questions about error handling using retrofit combined with RxAndroid, but i am not able to set my configuration right.

What do I want to accomplish:

  1. when receiving a 4xx code: handle it on onError()
  2. when receiving a 2xx code:

    -> try to parse to expected response and deliver it onNext()

    -> If not possible try to convert the JSON answer to MyAPIError class (simple POJO with errorNum and message) and deliver it on onError.

So either 2xx or 4xx http codes might end up in onError().

What do I have at the moment:

ServiceGenerator.java

public class ServiceGenerator {

    private static final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor()
            .setLevel(HttpLoggingInterceptor.Level.BODY);


    private static final Gson gson = new GsonBuilder()
            .registerTypeAdapter(DateTime.class, (JsonDeserializer<DateTime>) (json, typeOfT, context) -> new DateTime(json.getAsJsonPrimitive().getAsLong())).create();


    public static Retrofit buildRetrofit() {
        return new Retrofit.Builder()
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .baseUrl("....myURL...")
                .client(getOkHttpClient()).build();
    }

    private static OkHttpClient getOkHttpClient() {
        return new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .addInterceptor(chain -> {
                    Request request = chain.request().newBuilder()
                               .addHeader(ProductionSettings.HEADER_KEY_TOKEN, "myToken here")
                                .build();
                    return chain.proceed(request);
                })
                .followRedirects(true)
                .followSslRedirects(true)
                .build();
    }


    public static <S> S createService(final Class<S> serviceClass) {
        return buildRetrofit().create(serviceClass);
    }
}

NetworkComunnication.java

public class NetworkCommunication implements UserAPI {
    private static NetworkCommunication instance;
    private final UserAPI userAPI;

    private NetworkCommunication() {
        this.userAPI = ServiceGenerator.createService(UserAPI.class);
    }

    public static NetworkCommunication getInstance() {
        if (instance == null) {
            instance = new NetworkCommunication();
        }
        return instance;
    }

    @Override
    public Observable<UserResponse> updateUser(@Path(UsersSchema.ObjectId) String objectId, @Body final Map<String, Object> body) {
        return userAPI.updateUser(objectId, body);
    }
}

UserIteractor.java

public class UserIteractor {
    private final UserMapper mapper;

    public UserIteractor() {
        this.mapper = new UserMapper();
    }

    public Observable<Boolean> updateUser(Long userObjectID, UserViewModel model) {
        Map<String, Object> reqBody = mapper.mapToUpdateRequestBody(model);
        return NetworkCommunication
                .getInstance()
                .updateUser(userObjectID, reqBody)
                .map(prodUserResponse -> true);
    }

}

I would like to handle everything before it gets to UserInteractor class, so it would be generic for all Interactors and I wouldn't have to make the same logic for all requests. How can I achieve this to be as generic as possible and as "top" as possible?

来源:https://stackoverflow.com/questions/43047055/retrofit-2-rxandroid-handle-errors-4xx-and-some-200

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!