- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在retrofit 2之前,有一种集中处理erros的方式——
new retrofit.RestAdapter.Builder()
.setEndpoint(apiUrl)
.setLogLevel(retrofit.RestAdapter.LogLevel.FULL)
.setErrorHandler(new CustomErrorHandler(ctx))
但是现在在Retrofit 2中,RestAdapter已经重命名为Retrofit
并且没有setErrorHandler()
。有没有办法使用 Retrofit.Builder()
集中处理错误?
最佳答案
好吧,您所要做的就是使用自定义回调创建自定义 CallAdapter
,以应对失败情况。 Retrofit 存储库有一个显示自定义 CallAdapter
的示例。您可以在 retrofit/samples 找到它.
这是一个显示自定义 CallAdapter
的示例(不适用于 2.2.0 之前的版本):
/*
* Copyright (C) 2015 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.retrofit;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.concurrent.Executor;
import javax.annotation.Nullable;
import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Callback;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.http.GET;
/**
* A sample showing a custom {@link CallAdapter} which adapts the built-in {@link Call} to a custom
* version whose callback has more granular methods.
*/
public final class ErrorHandlingAdapter {
/** A callback which offers granular callbacks for various conditions. */
interface MyCallback<T> {
/** Called for [200, 300) responses. */
void success(Response<T> response);
/** Called for 401 responses. */
void unauthenticated(Response<?> response);
/** Called for [400, 500) responses, except 401. */
void clientError(Response<?> response);
/** Called for [500, 600) response. */
void serverError(Response<?> response);
/** Called for network errors while making the call. */
void networkError(IOException e);
/** Called for unexpected errors while making the call. */
void unexpectedError(Throwable t);
}
interface MyCall<T> {
void cancel();
void enqueue(MyCallback<T> callback);
MyCall<T> clone();
// Left as an exercise for the reader...
// TODO MyResponse<T> execute() throws MyHttpException;
}
public static class ErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != MyCall.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalStateException(
"MyCall must have generic type (e.g., MyCall<ResponseBody>)");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) returnType);
Executor callbackExecutor = retrofit.callbackExecutor();
return new ErrorHandlingCallAdapter<>(responseType, callbackExecutor);
}
private static final class ErrorHandlingCallAdapter<R> implements CallAdapter<R, MyCall<R>> {
private final Type responseType;
private final Executor callbackExecutor;
ErrorHandlingCallAdapter(Type responseType, Executor callbackExecutor) {
this.responseType = responseType;
this.callbackExecutor = callbackExecutor;
}
@Override public Type responseType() {
return responseType;
}
@Override public MyCall<R> adapt(Call<R> call) {
return new MyCallAdapter<>(call, callbackExecutor);
}
}
}
/** Adapts a {@link Call} to {@link MyCall}. */
static class MyCallAdapter<T> implements MyCall<T> {
private final Call<T> call;
private final Executor callbackExecutor;
MyCallAdapter(Call<T> call, Executor callbackExecutor) {
this.call = call;
this.callbackExecutor = callbackExecutor;
}
@Override public void cancel() {
call.cancel();
}
@Override public void enqueue(final MyCallback<T> callback) {
call.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, Response<T> response) {
// TODO if 'callbackExecutor' is not null, the 'callback' methods should be executed
// on that executor by submitting a Runnable. This is left as an exercise for the reader.
int code = response.code();
if (code >= 200 && code < 300) {
callback.success(response);
} else if (code == 401) {
callback.unauthenticated(response);
} else if (code >= 400 && code < 500) {
callback.clientError(response);
} else if (code >= 500 && code < 600) {
callback.serverError(response);
} else {
callback.unexpectedError(new RuntimeException("Unexpected response " + response));
}
}
@Override public void onFailure(Call<T> call, Throwable t) {
// TODO if 'callbackExecutor' is not null, the 'callback' methods should be executed
// on that executor by submitting a Runnable. This is left as an exercise for the reader.
if (t instanceof IOException) {
callback.networkError((IOException) t);
} else {
callback.unexpectedError(t);
}
}
});
}
@Override public MyCall<T> clone() {
return new MyCallAdapter<>(call.clone(), callbackExecutor);
}
}
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://httpbin.org")
.addCallAdapterFactory(new ErrorHandlingCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build();
HttpBinService service = retrofit.create(HttpBinService.class);
MyCall<Ip> ip = service.getIp();
ip.enqueue(new MyCallback<Ip>() {
@Override public void success(Response<Ip> response) {
System.out.println("SUCCESS! " + response.body().origin);
}
@Override public void unauthenticated(Response<?> response) {
System.out.println("UNAUTHENTICATED");
}
@Override public void clientError(Response<?> response) {
System.out.println("CLIENT ERROR " + response.code() + " " + response.message());
}
@Override public void serverError(Response<?> response) {
System.out.println("SERVER ERROR " + response.code() + " " + response.message());
}
@Override public void networkError(IOException e) {
System.err.println("NETWORK ERROR " + e.getMessage());
}
@Override public void unexpectedError(Throwable t) {
System.err.println("FATAL ERROR " + t.getMessage());
}
});
关于android - 集中式错误处理改造 2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35029936/
我已经使用 vue-cli 两个星期了,直到今天一切正常。我在本地建立这个项目。 https://drive.google.com/open?id=0BwGw1zyyKjW7S3RYWXRaX24tQ
您好,我正在尝试使用 python 库 pytesseract 从图像中提取文本。请找到代码: from PIL import Image from pytesseract import image_
我的错误 /usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference
我已经训练了一个模型,我正在尝试使用 predict函数但它返回以下错误。 Error in contrasts<-(*tmp*, value = contr.funs[1 + isOF[nn]])
根据Microsoft DataConnectors的信息我想通过 this ODBC driver 创建一个从 PowerBi 到 PostgreSQL 的连接器使用直接查询。我重用了 Micros
我已经为 SoundManagement 创建了一个包,其中有一个扩展 MediaPlayer 的类。我希望全局控制这个变量。这是我的代码: package soundmanagement; impo
我在Heroku上部署了一个应用程序。我正在使用免费服务。 我经常收到以下错误消息。 PG::Error: ERROR: out of memory 如果刷新浏览器,就可以了。但是随后,它又随机发生
我正在运行 LAMP 服务器,这个 .htaccess 给我一个 500 错误。其作用是过滤关键字并重定向到相应的域名。 Options +FollowSymLinks RewriteEngine
我有两个驱动器 A 和 B。使用 python 脚本,我在“A”驱动器中创建一些文件,并运行 powerscript,该脚本以 1 秒的间隔将驱动器 A 中的所有文件复制到驱动器 B。 我在 powe
下面的函数一直返回这个错误信息。我认为可能是 double_precision 字段类型导致了这种情况,我尝试使用 CAST,但要么不是这样,要么我没有做对...帮助? 这是错误: ERROR: i
这个问题已经有答案了: Syntax error due to using a reserved word as a table or column name in MySQL (1 个回答) 已关闭
我的数据库有这个小问题。 我创建了一个表“articoli”,其中包含商品的品牌、型号和价格。 每篇文章都由一个 id (ID_ARTICOLO)` 定义,它是一个自动递增字段。 好吧,现在当我尝试插
我是新来的。我目前正在 DeVry 在线学习中级 C++ 编程。我们正在使用 C++ Primer Plus 这本书,到目前为止我一直做得很好。我的老师最近向我们扔了一个曲线球。我目前的任务是这样的:
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我的网站中有一段代码有问题;此错误仅发生在 Internet Explorer 7 中。 我没有在这里发布我所有的 HTML/CSS 标记,而是发布了网站的一个版本 here . 如您所见,我在列中有
如果尝试在 USB 设备上构建 node.js 应用程序时在我的树莓派上使用 npm 时遇到一些问题。 package.json 看起来像这样: { "name" : "node-todo",
在 Python 中,您有 None单例,在某些情况下表现得很奇怪: >>> a = None >>> type(a) >>> isinstance(a,None) Traceback (most
这是我的 build.gradle (Module:app) 文件: apply plugin: 'com.android.application' android { compileSdkV
我是 android 的新手,我的项目刚才编译和运行正常,但在我尝试实现抽屉导航后,它给了我这个错误 FAILURE: Build failed with an exception. What wen
谁能解释一下?我想我正在做一些非常愚蠢的事情,并且急切地等待着启蒙。 我得到这个输出: phpversion() == 7.2.25-1+0~20191128.32+debian8~1.gbp108
我是一名优秀的程序员,十分优秀!