is there anyone can help? I meet some problem that I would like to handle the connect error return by server response.
Like this :
When I request to server and I get some json like below:
{"Data":null,"Result":{"State":-2,"Msg":"Parameter input from user error."}} I would like to handle this by Rxjava with retryWhen
Then , I write some Observer to handle some parse error or something wrong from server .
abstract class RetrofitResultObserver<T> : Observer<Result<T>> { override fun onSubscribe(d: Disposable) {} override fun onComplete() { } override fun onError(e: Throwable) { // e.printStackTrace() val resultException: RetrofitResultException //non-200 error if (e is HttpException) { resultException = RetrofitResultException(e.code(), "non-200 HTTP ERROR", e) Log.e(TAG, "Retrofit Http Error") onFailure(resultException) } else if (e is IOException) { resultException = RetrofitResultException(0, "NETWORK ERROR", e) Log.e(TAG, "Retrofit Network Error") onFailure(resultException) } else if (e is UnknownFormatConversionException || e is JsonIOException || e is JsonParseException) { resultException = RetrofitResultException(RetrofitResultException.PARSE_ERROR, "PARSE ERROR", e) Log.e(TAG, "Retrofit Parse Error") onFailure(resultException) } else if(e is RetrofitResultException){ Log.e(TAG, "RetrofitResultException , ${e.code} , ${e.msg}") onFailure(e) } else{ returnUnKnow(e) } } private fun returnUnKnow(e: Throwable) { Log.d(TAG, e.toString()) val resultException = RetrofitResultException(RetrofitResultException.UNKNOWN, "UNKNOWN ERROR", e) // ToastUtils.showShort("UnKnow error"); onFailure(resultException) } override fun onNext(t: Result<T>) { if (t == null) { onError(RetrofitResultException(RetrofitResultException.PARSE_ERROR, "Return null result from server")) return } val result = t.result if (result?.code == null) { onError(RetrofitResultException(RetrofitResultException.PARSE_ERROR, "Return null data from server")) return } // Result result = (Result)t; if (Constants.Http.SUCCESS === t.result!!.code) { try { onSuccess(t.value!!) } catch (e: Exception) { e.printStackTrace() } } else { onResultCode(t.result!!.code) } } /** * call this when getting non SUCCESS code */ protected fun onResultCode(resultCode: Int) { Log.d(TAG, "server result [$resultCode]") onError(RetrofitResultException(resultCode, "Return error result from server")) } open fun onFailure(e: RetrofitResultException) { e.printStackTrace() } abstract fun onSuccess(data: Collection<T>) class RetrofitResultException : RuntimeException { var code: Int = 0 var msg: String constructor(code: Int, msg: String) { this.code = code this.msg = msg } constructor(code: Int, msg: String, e: Throwable) { this.code = code this.msg = msg } override fun toString(): String { return "http code = " + code + "\n cause = " + msg + "\n" + super.toString() } companion object { const val UNKNOWN = 1000 const val PARSE_ERROR = 1001 const val RESULT_CODE_ERROR = 1002 } } companion object { const val TAG = "RetrofitResult" } } All handle by Observer is work fine ,
But I have some problem with here :
I write the kotlin extension to a handle error by retryWhen
fun <T> Observable<T>.retryWhenError(retryCount: Int, delayInSeconds: Long): Observable<T> { return retryWhen { errors -> errors.zipWith( Observable.range(1, retryCount), BiFunction { throwable: Throwable, count: Int -> Pair(throwable, count) }) .flatMap { count: Pair<Throwable, Int> -> LogTool.e("test ${count.first}") LogTool.e("test ") if (count.second < retryCount) { Observable.timer(delayInSeconds, TimeUnit.SECONDS) } else { Observable.error(count.first) } } } } But when I test it and server return the error code like this with my Observer and run the onError()
Which I call my http API:
fun fetchGpsApi(fetchGPSRequest: FetchGPSRequest, result: RetrofitResultObserver<FetchGPSResult>) { repo.fetchGps(fetchGPSRequest) .retryWhenError(2,5) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(result) } Which server return:
{"Data":null,"Result":{"State":-2,"Msg":"Parameter input from user error."}} And I see the log I print on my extension function is always not show, mean that doesn,t go into the retryWhenError Extension ...
How can I fix this problem ? Can any god coder can help?
https://stackoverflow.com/questions/65606118/android-kotlin-rxjava-retrofit-with-http-request-handle-error-with-retrywhen-a January 07, 2021 at 11:06AM
没有评论:
发表评论