Модификация 2 + ошибка обработки Rxjava

Так что я уже получаю токен от Json, когда вход в систему сделан без проблем, и получаю хэш

Но когда ответ от сервера является ошибкой, я не могу получить сообщение Json ({сообщение:"Ошибка: неправильный адрес электронной почты} "), потому что в onError мы получаем в качестве аргумента только Throwable, а не класс модели, как в on

Как я могу получить сообщение JSON от сервера 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

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;
}

}

3 ответа

Решение

Я нашел решение, у меня есть класс приложения, который создает Retrofit, а затем я просто создал ResponseBody и преобразовал с помощью 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;
                }

JSon получил: {"error":4041,"message":"Email not found"}, поэтому класс Error, я просто создал переменное сообщение, потому что я просто хочу показать сообщение пользователю

Вы смешиваете логическую ошибку (по какой-то причине не удалось войти) с ошибкой приложения. Если ваш сервер отправляет ответ с HTTP 200 и допустимым json в случае неудачного входа в систему, ваше приложение вообще не будет вызывать onError.

Таким образом, в основном вам нужно проверить (успешный) ответ от сервера и решить на основании предоставленного json, был ли вход успешным или нет.

Например, onError следует вызывать, если сервер недоступен или не может предоставить действительный ответ.

Редактировать: я не знаю, какова ваша TokenResponse содержит, но в основном ответ для входа в систему должен быть одинаковым, независимо от того, был он успешным или нет. Затем вы просто проверяете TokenResponse, чтобы узнать, содержит ли результат ошибки или нет.

Проверьте этот ответ в качестве примера: /questions/38828293/kak-mne-obrabotat-oshibki-otveta-ispolzuya-retrofit-i-rxjavarxandroid/38828303#38828303

      
 override fun onError(e: Throwable?) {
                    if (e is HttpException) {
                        Log.i("", "Status code: " + e.code())
                        Log.i("", "Response: " + e.response()?.errorBody()?.string())
                    }
                }

Меня устраивает!

Другие вопросы по тегам