簡體   English   中英

Android RxJava2-引發錯誤時如何進行api調用?

[英]Android RxJava2 - How to make api call when error is thrown?

因此,我目前正在使用flatMap將API調用鏈接在一起,並且在我的用例中效果很好。 如果我的一個呼叫返回失敗的響應代碼,那么我將傳遞一個錯誤單,其中包含一個throwable,並帶有一條消息,指出哪個呼叫失敗並且一直持續。 這是我現在的做法:

dataManager.apiCall1(dataManager.sessionId!!)
        .subscribeOn(schedulerProvider.io())
        .observeOn(schedulerProvider.ui())
        .flatMap{apiCall1Response ->
            if (apiCall1Response.isSuccessful && apiCall1Response.body() != null) {
                // First api call was successful, execute api call 2.
                return@flatMap dataManager.apiCall2(apiCall1Response.importantVal)
            } else {
                // First api call failed 
                return@flatMap Single.error<Throwable>(Throwable("First api call failed."))
            }
        }.flatMap{apiCall2Response ->
            if (apiCall2Response != null && apiCall2Response.isSuccessful && apiCall2Response.body() != null) {
                // Second api call was successful, execute api call 3.
                return@flatMap dataManager.apiCall3(apiCall2Response.importantVal)
            } else if (apiCall2Response is Throwable) {
                // Api Call 1 Failed.
                return@flatMap Single.error<Throwable>(apiCall2Response)
            } else {
                // Second api call failed
                return@flatMap Single.error<Throwable>(Throwable("Second api call failed."))
            }
        }.subscribe({apiCall3Response ->
            if (apiCall3Response is Response<*> && apiCall3Response.body() != null) {
               // Success!
               navigator?.successful(response)
            } else if (apiCall3Response is Throwable) {
               // Something failed from before.
               navigator?.handleError(apiCall3Response)
            } else {
               // Third api call failed, handle error
               navigator!!.handleError(Throwable("Api call 3 failed."))
            }
        }, {throwable ->
            navigator!!.handleError(throwable)
        })

好吧,現在我意識到,如果我的第一個api調用成功並且其他任何調用都失敗,則需要進行其他api調用。 這是登錄用戶的一系列調用,如果登錄調用成功,但是下一次調用失敗,則需要調用api注銷端點。 我知道在subscribe()方法中創建另一個單一的方法是不好的做法,所以我不想這樣做。 我寧願通過注銷調用,但問題是由於注銷和apiCall3都返回空主體,因此無法知道在subscribe方法中返回哪個api調用。 如果apiCall3失敗,我也想調用注銷端點,但是不確定是否可以。 這是我正在嘗試做的事情:

dataManager.apiCall1(dataManager.sessionId!!)
        .subscribeOn(schedulerProvider.io())
        .observeOn(schedulerProvider.ui())
        .flatMap{apiCall1Response ->
            if (apiCall1Response.isSuccessful && apiCall1Response.body() != null) {
                // First api call was successful, execute api call 2.
                return@flatMap dataManager.apiCall2(apiCall1Response.importantVal)
            } else {
                // First api call failed 
                return@flatMap Single.error<Throwable>(Throwable("First api call failed."))
            }
        }.flatMap{apiCall2Response ->
            if (apiCall2Response != null && apiCall2Response.isSuccessful && apiCall2Response.body() != null) {
                // Second api call was successful, execute api call 3.
                return@flatMap dataManager.apiCall3(apiCall2Response.importantVal)
            } else if (apiCall2Response is Throwable) {
                // Api Call 1 Failed.
                return@flatMap Single.error<Throwable>(apiCall2Response)
            } else {
                // Second api call failed, logout
                return@flatMap dataManager.logoutApiCall()
            }
        }.subscribe({apiCall3OrLogoutResponse ->
            // I would like to be able to determine which call this response is from. That is the question. 
            if (apiCall3OrLogoutResponse is Response<*> && apiCall3OrLogoutResponse.body() != null) {
               // Success!
               navigator?.successful(response)
            } else if (apiCall3OrLogoutResponse is Throwable) {
               // Something failed from before.
               navigator?.handleError(apiCall3OrLogoutResponse)
            } else {
               // Third api call or logout call failed, handle error
               if (apiCall3OrLogoutResponse is ApiCall3) {
                  // Api Call 3 failed. 
                  // Somehow call logout api endpoint
               } else if (apiCall3OrLogoutResponse is LogoutCall {
                  // Logout call failed.
                  navigator?.handleError(Throwable("Logout failed."))  
               }       
            }
        }, {throwable ->
            navigator!!.handleError(throwable)
        })

有一個更好的方法嗎? 我的用例是進行三個連續的api調用,如果第一個失敗,則將一個throwable發送給訂閱者,如果第一個成功,然后失敗,則進行另一個api調用。

我通過拋出自定義異常而不是向下傳遞Single.error並在flatMapCompletable中而不是在訂閱中檢查了我的最終調用來解決了這一問題。 然后,如果異常不是登錄異常,則在doOnError中調用注銷端點。

dataManager.apiCall1(dataManager.sessionId!!)
    .subscribeOn(schedulerProvider.io())
    .observeOn(schedulerProvider.ui())
    .flatMap{apiCall1Response ->
        if (apiCall1Response.isSuccessful && apiCall1Response.body() != null) {
            // First api call was successful, execute api call 2.
            return@flatMap dataManager.apiCall2(apiCall1Response.importantVal)
        } else {
            // First api call failed 
            throw ApiCall1Exception("Api Call 1 failed.")
        }
    }.flatMap{apiCall2Response ->
        if (apiCall2Response != null && apiCall2Response.isSuccessful && apiCall2Response.body() != null) {
            // Second api call was successful, execute api call 3.
            return@flatMap dataManager.apiCall3(apiCall2Response.importantVal)
        } else {
            // Second api call failed
            throw Throwable("Api call 2 failed.")
        }
    }.flatMapCompletable{apiCall3Response ->
        if (apiCall3Response.body() != null) {
            // All api calls were successful!
            Completable.complete()
        } else {
            // Third api call failed.
            throw Throwable("Api call 3 failed.")
        }    
    }.doOnError{throwable ->
        if (throwable !is ApiCall1Exception) {
            // Api call 1 was successful, but something else failed, call logout endpoint.
            dataManager.logout()
                  .subscribeOn(schedulerProvider.io())
                  .observeOn(schedulerProvider.ui())
        }
    }.subscribe({
        // Success!
        navigator?.success()
    }, {throwable ->
        // Something failed!
        navigator?.handleError(throwable)
    })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM