私はAPIretorift
をヒットし、ユーザーに関連する記事のリストを取得するために使用しています。渡されたトークンが期限切れの場合、API はエラーをスローします。その場合、API を呼び出して新しいトークンを取得する必要があり、再度APIを呼び出す必要があります。getAricle
getArticle
refreshToken
getArticle
ApiController.createRx().getArticle(token)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ response -> toast(response.body().url) }, { e ->
println(e.printStackTrace())
if(e is HttpException && e.code() in arrayOf(401,403)){
//Here I want to call refresh tolken api
toast("Auth error")
}
else
toast(R.string.something_went_wrong)
})
編集
与えられた答えは何らかの方向性を示しましたが、それらは私の質問に対する直接的な答えではありません。これが解決方法ですが、これはより良いコードにリファクタリングできると思います
ApiController.createRx().getArticle(Preference.getToken())
.flatMap { value ->
if (value.code() in arrayOf(403, 401)) {
ApiController.refreshToken()
ApiController.createRx().getArticle(Preference.getToken())
} else Observable.just(value)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ response -> println("Success") }, { e ->
e.printStackTrace()
toast(R.string.something_went_wrong)
})
fun refreshToken() {
val token:String?=ApiController.createRx().refreshToken(Preferences.getRefreshToken()).blockingFirst()?.body()?.token
if (token != null) Preferences.setAuthToken(token)
}
編集
コードをもう少しきれいなバージョンにリファクタリングしました
Observable.defer { ApiController.createRx().getArticle(Preferences.getToken()) }
.flatMap {
if (it.code() in arrayOf(401, 403)) {
ApiController.refreshToken()
Observable.error(Throwable())
} else Observable.just(it)
}
.retry(1)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({println("Success") }, {
it.printStackTrace()
toast(R.string.something_went_wrong)
})
fun refreshToken() {
var token: String? = null
try {
token = createRx().refreshToken(Preferences.getRefreshToken()).blockingFirst().body()!!.token
} catch (e: Exception) {
throw e
}
println("saving token")
if (token != null) Preferences.setAuthToken(token)
}
編集
最終的なリファクタリングされたコードについては、私の回答を確認してください