改造错误处理

时间:2014-11-01 10:53:53

标签: java android error-handling retrofit

我将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 个答案:

答案 0 :(得分:8)

当您构建RestAdapter时,您可以提供映射到自定义例外的error handler,它绕过failure对任何4xx的Callback<T>的调用/ 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界面开始的一个重要原因。如果这是您需要的常用用法,则使用同步调用并返回对象类型可能更有意义。我并不完全知道你的用处,但这似乎更合适。