2014-11-01 29 views
4

我在下面的類中包裝了我的Retrofit代碼。如果從發佈的代碼中可以看出,它與OAuth使用的是一個寧靜的服務。改裝錯誤處理

什麼是錯誤處理的好方法? REST服務器以json格式返回錯誤消息。我想通過拋出我班的一些例外來處理這個信息。我正在嘗試做下面的事情。但這是不錯的設計?混合回調和異常拋出一個好主意?有沒有更好的辦法?

使用下面的方法,我可以從我的自定義異常中獲取i18l消息,並將它們提供給用戶。

public class RestClient implements IRestClient { 
    private IRestAPI api; 

    /** 
    * 
    * @param accessToken 
    */ 
    public RestClient(final String accessToken) 
    { 
     RequestInterceptor requestInterceptor = new RequestInterceptor() 
     { 
      @Override 
      public void intercept(RequestFacade request) { 
       request.addHeader("Authorization", "Bearer " + accessToken); 
      } 
     }; 

     RestAdapter restAdapter = new RestAdapter.Builder() 
       .setEndpoint(Config.ENDPOINT) 
       .setRequestInterceptor(requestInterceptor) 
       .build(); 
     api = restAdapter.create(IRestAPI.class); 
    } 

    @Override 
    public void requestSomething(final Callback callback) { 
     api.getSomething(new Callback<Something>() { 
      @Override 
      public void success(Something something, Response response) { 
       callback.success(something, response); 
      } 

      @Override 
      public void failure(RetrofitError error) { 
       if(error.getMessage().getId().euqals(ACCESS_TOKEN_EXPIRED)) 
       { 
        throw new AccessTokenExpired(); 
       } 
       else if(error.getMessage().getId().euqals(USER_NOT_FOUND)) 
       { 
        throw new UsernamePasswordNotFound(); 
       } 
       else // something else happened... 
       { 
        throw error; 
       } 
      } 
     }); 
    } 

    @Override 
    public void deleteSomething(final Callback callback) { 
     api.deleteSomething(new Callback<Something>() { 
      @Override 
      public void success(Something something, Response response) { 
       callback.success(something, response); 
      } 

      @Override 
      public void failure(RetrofitError error) { 
       if(error.getMessage().getId().euqals(SOMETHING_NOT_FOUND)) 
       { 
        ... 
        ... 
        Different exceptions 
       } 
       ... 
      } 
     }); 
    } 

} 

當然,我將不得不創建我自己的回調接口,只有成功的方法。

+1

您可以隨時在RestAdapter構建器中使用Retrofit的ErrorHandler。 http://square.github.io/retrofit/javadoc/retrofit/ErrorHandler.html – daentech 2014-11-01 11:28:40

回答

8

當您生成RestAdapter,你可以提供一個error handler映射出你的自定義異常,它繞過任何東西在Callback<T>調用failure的4xx/5xx系列。作爲一個真正的人爲的例子:

public class Scratch { 
    public static void main(String[] args) { 
     Endpoints e = new RestAdapter.Builder() 
       .setEndpoint("http://google.com") 
       .setLogLevel(RestAdapter.LogLevel.FULL) 
       .setErrorHandler(new ErrorHandler() { 
        @Override 
        public Throwable handleError(RetrofitError cause) { 
         switch (cause.getResponse().getStatus()) { 
          case 400: 
           /* Handle the expected body format */ 
           cause.getBody(); 
           throw new RuntimeException("Bad Request"); 
          default: 
           /* Things and stuff */ 
           throw new RuntimeException(""); 
         } 
        } 
       }) 
       .build() 
       .create(Endpoints.class); 

     e.getGoogle(new Callback<Response>() { 
      @Override 
      public void success(Response response, Response response2) { 
       System.out.println("Got it"); 
      } 

      @Override 
      public void failure(RetrofitError error) { 
       System.err.println("This won't ever be seen due to the error handler."); 
      } 
     }); 
    } 

    private static interface Endpoints { 
     @GET("/foo/bar") 
     void getGoogle(Callback<Response> callback); 
    } 
} 

編輯:通過這樣做,但是,你可能犧牲一個很大的原因,你會想使用Callback接口開始。如果這是您需要的常見用法,則使用同步調用並返回對象類型可能更有意義。我不完全知道你的用法說這是必要的,但似乎它可能更合適。

+0

是的,但我想爲不同的方法有不同的例外......或者至少我認爲我是這樣做的。我完全不太確定這種方法。假設我有一個createSomething方法。這可能會引發AlreadyExistsException。如果我有一個deleteSomething方法,它可能會拋出SomethingNotFoundException ...有道理? – user672009 2014-11-01 14:20:43

+0

我真的不認爲你會這麼做,至少在這個級別上。您正在使用的任何HTTP服務都應使用標準錯誤代碼(或者有一些標準來告訴您爲什麼請求失敗)。因此,在我的答案中的「switch」示例中,將您的評論作爲模板使用,可以將'409'映射爲您的'ConflictException','404'作爲狀態碼:異常映射映射到您的'NotFoundException'。當你打電話給4xx/5xx時 - 不管它是什麼,你會得到一個標準的例外。 – nerdwaller 2014-11-01 14:25:11

+0

當然,這樣做的負面影響在於,如果您希望這是一件常見的事情,那麼您可以通過拋回其他代碼來犧牲異步調用的某些好處 - 可能使用「Callback」接口是錯誤的方法供您使用。 – nerdwaller 2014-11-01 14:26:21