Использование retryWhen для обновления токенов на основе кода ошибки http
Я нашел этот пример наКак обновить токен oauth с помощью moya и rxswift который мне пришлось немного изменить, чтобы получить для компиляции. Этот код работает на 80% для моего сценария. Проблема в том, что он будет работать для всех ошибок http, а не только для ошибок 401. Я хочу, чтобы все мои другие ошибки http передавались как ошибки, чтобы я мог обрабатывать их в другом месте и не глотать их здесь.
С этим кодом, если я получуHttpStatus 500
, он будет запускать код аутентификации 3 раза, что явно не то, что я хочу.
Я пытался изменить этот код, чтобы обрабатывать только ручку401
ошибки, но кажется, что независимо от того, что я делаю, я не могу заставить код для компиляции. Это всегда жалуется на неправильный тип возврата,"Cannot convert return expression of type Observable<Response> to return type Observable<Response>"
что не имеет смысла для меня ..
Что я хочу: обрабатывать 401, но останавливаться на всех других ошибках
import RxSwift
import KeychainAccess
import Moya
public extension ObservableType where E == Response {
/// Tries to refresh auth token on 401 errors and retry the request.
/// If the refresh fails, the signal errors.
public func retryWithAuthIfNeeded() -> Observable<E> {
return self.retryWhen {
(e: Observable<ErrorType>) in
return Observable.zip(e, Observable.range(start: 1, count: 3), resultSelector: { $1 })
.flatMap { i in
return AuthProvider.sharedInstance.request(
.LoginFacebookUser(
accessToken: AuthenticationManager.defaultInstance().getLoginTokenFromKeyChain(),
useFaceBookLogin: AuthenticationManager.defaultInstance().isFacebookLogin())
)
.filterSuccessfulStatusCodes()
.mapObject(Accesstoken.self)
.catchError {
error in
log.debug("ReAuth error: \(error)")
if case Error.StatusCode(let response) = error {
if response.statusCode == 401 {
// Force logout after failed attempt
log.debug("401:, force user logout")
NSNotificationCenter.defaultCenter().postNotificationName(Constants.Notifications.userNotAuthenticated, object: nil, userInfo: nil)
}
}
return Observable.error(error)
}.flatMapLatest({
token -> Observable<Accesstoken> in
AuthenticationManager.defaultInstance().storeServiceTokenInKeychain(token)
return Observable.just(token)
})
}
}
}
}