Retrofit 2 + Rxjava handling error

14,912

Solution 1

I found a solution, I have a application class that Creates a Retrofit and then i just created a ResponseBody and converted using responseBodyConverter(,)

                @Override
                public void onError(Throwable e) {
                    if (e instanceof HttpException) {
                        ResponseBody body = ((HttpException) e).response().errorBody();

                        Converter<ResponseBody, Error> errorConverter =
                            application.getRetrofit().responseBodyConverter(Error.class, new Annotation[0]);
                    // Convert the error body into our Error type.
                        try {
                            Error error = errorConverter.convert(body);
                            Log.i("","ERROR: " + error.message);
                            mLoginView.errorText(error.message);
                        } catch (IOException e1) {
                        e1.printStackTrace();
                        }
                     }



                static class Error{
                String message;
                }

the JSon received was {"error":4041,"message":"Email not found"} thas why the class Error, i just created a variable message because i just want need to show the message to the user

Solution 2

You are mixing a logical error (login failed for some reason) with an application error. If your server sends response with HTTP 200 and a valid json in case of failed login, your application will not call onError at all.

So basically you need to check the (successful) response from the server and decide based on the provided json if the login was successful or not.

onError should be called, for example, in case the server is not reachable or fails to deliver a valid response.

Edit: I don't know what your TokenResponse contains but basically the response for a login should be the same, no matter if it was successful or not. You then just check the TokenResponse to find out if the result contains errors or not.

Check this answer as an example: https://stackoverflow.com/a/31159671/180538

Share:
14,912

Related videos on Youtube

Diogo Rosa
Author by

Diogo Rosa

Graduated in Engineering of Telecomunications and Informatics, Currently working in Android Applications. My skills are mostly Java

Updated on September 20, 2022

Comments

  • Diogo Rosa
    Diogo Rosa over 1 year

    So i already receive a token from the Json when the login is made without problems, and receive the hash

    But when the response from the server is a error, i cannot get the Json message ({message:"Error : wrong email} " because in the onError we only get as argument a Throwable and not a model class like in on

    how can i get a json message from server onError??

    final Observable<TokenResponse> observable = Service.login(userCredentials);
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<TokenResponse>() {
                    String error="";
    
                    @Override
                    public void onCompleted() {
                        mLoginView.whenLoginSucess();
                    }
    
                    @Override
                    public void onError(Throwable e) {
    
                        if (e instanceof HttpException) {
                            HttpException exception = (HttpException) e;
                            Response response = exception.response();
                            Converter<ResponseBody, ErrorFromServer> converter = new GsonConverterFactory()
                                    .responseBodyConverter(ErrorFromServer.class, Annotation[0]);
                            ErrorFromServer error = converter.convert(response.errorBody());
                        }
    
                        mLoginView.errorText(error);
    
                        e.printStackTrace();
    
                    }
    
                    @Override
                    public void onNext(TokenResponse tokenResponse) {
    
    
                        SharedPreferences.Editor editor = sharedP.edit();
                        editor.putString("hash", tokenResponse.getToken());
                        editor.commit();
    
                        //getString return key value "hash" if there is no value, returns null
                        hash = sharedP.getString("hash",null);
    
    
    
    
                    }
                });
    

    TokenResponse code

    public class TokenResponse {
    @SerializedName("hash")
    @Expose
    private String token;
    
    @SerializedName("message")
    @Expose
    private String message;
    
    
    public String getMessage() {return message;}
    
    
    public String getToken() {
        return token;
    }
    

    }