1

I used Retrofit with RxJava like this:

 Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(HttpURL.BASE_URL)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .client(okHttpClient)
                .build();

and when the request error, such as password is wrong, the status code is 400, and the error msg will int the errorBoby to get me just like {code: 1000, message: "password is wrong"}.

However, the gons GsonConverterFactory will not fromJson in respone.getErrorBody , so I change my code just like this

 Call<Result<User>> call = ApiManger.get().getLoginApi().login1(login);
 call.enqueue(new Callback<Result<User>>() {
            @Override
            public void onResponse(Call<Result<User>> call, Response<Result<User>> response) {
                if (response.code() == 0) {
                    mLoginView.onLoginSuccess(response.body().getData());
                } else {
                    try {
                        Result result = new Gson().fromJson(response.errorBody().string(),Result.class);
                        ToastUtils.showShort(result.getMessage());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<Result<User>> call, Throwable t) {

            }
        });
        

so it can not be used with Rxjava, how can I change it?

Lewis
  • 304
  • 3
  • 10

3 Answers3

4

This can be done using Rx and here is how:

mSubscription.add(mDataManager.login(username, password)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Subscriber<User>() {
                            @Override
                            public void onCompleted() {

                            }

                            @Override
                            public void onError(Throwable e) {
                                if (NetworkUtil.isHttpStatusCode(e, 400) || NetworkUtil.isHttpStatusCode(e, 400)) {
                                    ResponseBody body = ((HttpException) e).response().errorBody();
                                    try {
                                        getMvpView().onError(body.string());
                                    } catch (IOException e1) {
                                        Timber.e(e1.getMessage());
                                    } finally {
                                        if (body != null) {
                                            body.close();
                                        }
                                    }
                                }
                            }

                            @Override
                            public void onNext(User user) {
                              //TODO Handle onNext
                            }
                        }));
            }

NetworkUtil

public class NetworkUtil {

    /**
     * Returns true if the Throwable is an instance of RetrofitError with an
     * http status code equals to the given one.
     */
    public static boolean isHttpStatusCode(Throwable throwable, int statusCode) {
        return throwable instanceof HttpException
                && ((HttpException) throwable).code() == statusCode;
    }
}
Ivan Milisavljevic
  • 2,048
  • 2
  • 13
  • 21
0

You need to serialise the error body string first

try something like this in your onNext():

if (!response.isSuccessful()) {
    JSONObject errorBody = new JSONObject(response.errorBody().string());
    String message = errorBody.getString("message");
}
bellol
  • 81
  • 5
0

Its usually a better idea to accept the response in a standard format -

Class Response{
    int code;
    String message;
    Data data; //////now data is the actual data that u need

    /////getter setters
    }

Now add an api method like this -

@GET("api_name")
    Observable<Response> getResponse(Params);

now call retrofit.getResponse(params) and you will get the observable, subscribe to that observable and check its value in onNext and implement your logic. So in your case(password error) the data would be null, but you will have code and message.

Debu
  • 615
  • 7
  • 21