2016-02-09 49 views
1

在我的Android項目中,我做了很多網絡請求(使用RetrofitRxJava),它們返回響應的自定義超類型,它可以包含有效或錯誤響應。RxJava通用方法來檢查用戶中的錯誤消息

AppResponse { 
    error=AppError { 
     code=12345, 
     message='null' 
    }, 
    data=null 
} 

的錯誤碼是沒有HTTP錯誤代碼,但是內容從與SimpleXML解析XML結果檢索。大約有4-5個錯誤代碼對於所有網絡請求都是相同的,例如會話超時等等。因此,我會編寫一個通用方法來檢查這些錯誤代碼的所有響應,並設置對策,例如請求新會話。

首先,我想到了使用OkHttp攔截器,但因爲我需要將我的結果解析爲適當的格式,所以我無法使用它。 解析結果後我使用RxJava,目前我正在檢查我的結果在訂閱方法中的響應。

restClient.requestHostList() 
      .subscribeOn(Schedulers.io()) 
      .unsubscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Subscriber<HostListResponse>() { 

       @Override 
       public void onError() { 

       } 
       @Override 
       public void onCompleted() { 

       } 

       @Override 
       public void onNext(HostListResponse hostListResponse) { 
        if (hostListResponse.isError()) { 

         if(hostListResponse.getError().getCode() == 12345) { 
          requestNewSession(); 
         } else if(hostListResponse.getError().getCode() == 23456) { 
          requestNewLogin(); 
         } 
        else { 
          //do some UI stuff here 
         } 

我不知道怎麼這裏着手,有沒有類似的東西可以在到達之前使用訂閱驗證結果,也許開始另一個網絡請求,或者倒不如啓動這個Transformer訂戶?我也在想,如果onErrorResumeNext()是通過將可觀測拋出一個錯誤的選擇,當未通過結果測試代碼,像這樣:

restClient.requestHostList() 
       .subscribeOn(Schedulers.io()) 
       .unsubscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .flatMap(new Func1<HostListResponse, Observable<Throwable>>() { 
        @Override 
        public Observable<Throwable> call(HostListResponse hostListResponse) { 
         if (hostListResponse.isError()) { 
          if(hostListResponse.getError().getCode() == 12345) { 
           throw new Exception(); 
          } 
         } 
        } 
       }) 
       .onErrorResumeNext(new Func1<Throwable, Observable<? extends Throwable>>() { 
        //do error handling here 
       }) 

回答

2

最後的解決方案是確定的。在錯誤情況下拋出異常是絕對正常的行爲。您可以使用compose運營商來包裝你的錯誤處理邏輯,並與所有改造觀測重複使用它:

static final int NO_ERROR = 0; 
static final int ERROR_A = 13; 
static final int ERROR_B = 666; 

Observable<BaseResponse> responseObservable = Observable.create(new Observable.OnSubscribe<BaseResponse>() { 
    @Override 
    public void call(Subscriber<? super BaseResponse> subscriber) { 
     subscriber.onNext(new BaseResponse(ERROR_A)); 
     //subscriber.onNext(new BaseResponse(ERROR_B)); 
     //subscriber.onNext(new BaseResponse(NO_ERROR)); 
     subscriber.onCompleted(); 
    } 
}); 

responseObservable 
     .compose(Utils.applyErrorHandler())//apply to this observable error handling logic 
     .subscribe(baseResponse -> { 
      System.out.println("ok"); 
     }, throwable -> { 
      System.out.println("error:" + throwable); 
     }); 
其處理錯誤

utils的類:

public static class Utils { 
    static Observable.Transformer schedulersTransformer = new Observable.Transformer<BaseResponse, BaseResponse>() { 
     @Override 
     public Observable<BaseResponse> call(Observable<BaseResponse> observable) { 
      return observable.doOnNext(baseResponse -> { 
       if (baseResponse.errorCode == ERROR_A) { 
        throw new RuntimeException("Error A"); 
       } else if (baseResponse.errorCode == ERROR_B) { 
        throw new RuntimeException("Error B"); 
       } 
      }); 
     } 
    }; 

    @SuppressWarnings("unchecked") 
    public static <T> Observable.Transformer<T, T> applyErrorHandler() { 
     return (Observable.Transformer<T, T>) schedulersTransformer; 
    } 
} 

基本思路是Transformer功能適用於觀察到它調用每個項目上都有doOnNext,檢查錯誤代碼並拋出相應的異常。在我的例子中,它被封裝到靜態幫助類Utils中,但它取決於您的要求,Transformer函數可以通過Dagger注入,並替換爲例如測試轉換函數。

可以在Dan Lew博客文章閱讀更多關於compose操作:http://blog.danlew.net/2015/03/02/dont-break-the-chain/

+0

謝謝您的回覆,我會立刻嘗試:) – Eve

相關問題