java 改造错误处理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26688559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Retrofit error handling
提问by user672009
I wrapped my Retrofit code in a class like below. If it's not clear from the code I'm posting it's interacting with a restful service with OAuth.
我将我的 Retrofit 代码包装在如下所示的类中。如果从我发布的代码中不清楚,它正在与带有 OAuth 的宁静服务进行交互。
What would be a good way to do error handling? The REST server returns an error message in json format. I would like to act on that message by throwing some exceptions from my class. I'm trying to do something like below. But is this good design? Is mixing callbacks and exception throwing a good idea? Is there a better way?
什么是进行错误处理的好方法?REST 服务器以 json 格式返回错误消息。我想通过从我的班级中抛出一些异常来根据该消息采取行动。我正在尝试做类似下面的事情。但这是好的设计吗?混合回调和异常抛出是个好主意吗?有没有更好的办法?
With the approach below I could get i18l messages from within my custom exceptions and toast them to the user.
使用下面的方法,我可以从我的自定义异常中获取 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
}
...
}
});
}
}
Naturally I would have to create my own call back interface with only a success method.
当然,我将不得不创建自己的回调接口,只有一个成功的方法。
回答by nerdwaller
When you build the RestAdapter
, you can provide an error handlerthat maps out to your custom exceptions, it bypasses the call to failure
in the Callback<T>
on anything 4xx/5xx. As a really contrived example:
当你建立了RestAdapter
,你可以提供一个错误处理程序映射出你的自定义异常,它绕过调用failure
的Callback<T>
任何东西的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);
}
}
edit: By doing this, however, you're potentially sacrificing a big reason why you'd want to use the Callback
interface to begin with. If this is a common use you will need, it may make more sense to use the sync calls and return your object type. I don't fully know your use to say that's necessary, but it seems as though it may be more appropriate.
编辑:但是,通过这样做,您可能会牺牲一个重要的原因,为什么您想Callback
开始使用该界面。如果这是您需要的常见用途,则使用同步调用并返回您的对象类型可能更有意义。我不完全知道你说那是必要的用法,但似乎它可能更合适。