Как мне обработать ошибки ответа, используя Retrofit и RxJava/RxAndroid?
У меня возникли проблемы при разработке, как обработать ошибку ответа с помощью дооснащения и RxAndroid. onError() вызывается, если есть сетевая ошибка или подобное, но мне нужно иметь возможность получить ответ, чтобы проверить, была ли ошибка аутентификации. Вместо этого я получаю токен с нулевой строкой, и я не могу понять, почему. Каков наилучший способ сделать это?
Это мой вызов RxAndroid на данный момент.
Client.getInstance().getService()
.getToken(usernameET.getText().toString(), passwordET.getText().toString())
.subscribe(new Subscriber<SiteInfo>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onNext(SiteInfo siteInfo) {
Log.d(TAG, "onNext "+ token.toString());
}
});
Это мой модифицированный сервис
@GET("my_url_here")
Observable<Token> getToken(
@Query("username") String username,
@Query("password") String password
);
Это мой текущий рестаптер
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(BASE_URL)
.build();
service = restAdapter.create(MyService.class);
И это мой токен-класс.
public class Token {
private String token;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@Override
public String toString() {
return token;
}
}
Как я должен идти об этом. Это может быть сделано в части RxAndroid или мне нужно добавить что-то в мой RestClient или, может быть, что-то еще полностью?
Благодарю.
редактировать
07-01 06:38:04.562 1680-1793/uk.co.dyolo.thing D/Retrofit﹕ ---> HTTP GET my_website_here
07-01 06:38:04.562 1680-1793/uk.co.dyolo.thing D/Retrofit﹕ ---> END HTTP (no body)
07-01 06:38:04.610 1680-1793/uk.co.dyolo.thing D/Retrofit﹕ <--- HTTP 200 my_website_here (48ms)
07-01 06:38:04.610 1680-1793/uk.co.dyolo.thing D/Retrofit﹕ : HTTP/1.1 200 OK
2 ответа
Я нашел решение
Сначала я расширил свой объект Token, чтобы иметь свойство error.
public class Token {
private String token;
private String error;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
@Override
public String toString() {
return token;
}
}
Затем я добавил в свою цепочку RxJava оператор, который может проверить, не является ли поле ошибки null
, И если есть ошибка, выведите пользовательское исключение, которое вызывает абонентов onError
позволяя мне справиться с этим.
if (token.getError() != null) {
throw OnErrorThrowable.from(new UserAuthenticationException(token.getError()));
}
И если есть ошибка, выведите пользовательское исключение, которое вызывает абонентов onError
позволяя мне справиться с этим.
if (e instanceof OnErrorThrowable){
if (e.getCause() instanceof UserAuthenticationException){
Log.d(TAG, "onError "+e.getCause().getMessage());
}
e.getCause().printStackTrace();
}
Это немного поздно, но если кто-нибудь сюда заходит, Retrofit 2 проходит в случае HttpException
в onError
обратный вызов всякий раз, когда запрос возвращается с сервера с кодом ошибки вне интервала [200,300)...
throwable -> {
if(throwable instanceof HttpException){
switch(((HttpException)throwable).code()){
// your error handling logic
}
}
}
Вы также можете получить весь ответ от этого объекта..