我正在使用改装2.3.0在我的应用程序中使用API但一周前我开始收到错误消息,现有代码无法在UI中显示错误消息。
以前,我使用errorBody.toString()然后在几个月后突然出现错误,然后上周我尝试使用errorBody.string()但它无法正常工作。现在它正在发挥作用。
我附上了服务器响应和我的错误处理的截图。这是我显示错误消息的代码。
private static void showToastForError(retrofit2.Response<Object> response, int requestType) {
if (response != null && response.errorBody() != null) {
try {
JSONObject jObjError = null;
try {
jObjError = new JSONObject(response.errorBody() != null ? response.errorBody().toString() : "");
Toast.makeText(Application.getAppContext(), jObjError.getString("message"), Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:0)
我认为你应该自定义调用适配器来处理错误。 这是我的自定义适配器
public final class ErrorHandlingAdapter {
/**
* A callback which offers granular callbacks for various conditions.
*/
public 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);
}
public interface MyCall<T> {
void cancel();
void enqueue(MyCallback<T> callback);
MyCall<T> clone();
boolean isExcute();
}
public static class ErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
@Override
public 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> {
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 <R1> R adapt(Call<R1> call) {
return (R) 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) {
// on that executor by submitting a Runnable. This is left as an exercise for the reader.
callbackExecutor.execute(new Runnable() {
@Override
public void run() {
int code = response.code();
if (code >= 200 && code < 300) {
callback.success(response);
} else if (code == 401) {
if (Storage.getInstance().isLogin())
Storage.getInstance().logout(App.self().getApplicationContext());
} 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) {
// on that executor by submitting a Runnable. This is left as an exercise for the reader.
callbackExecutor.execute(new Runnable() {
@Override
public void run() {
if (t instanceof IOException) {
if (call.isCanceled()) {
return;
}
callback.networkError((IOException) t);
Toast.makeText(App.self(), R.string.error_no_connect_internet, Toast.LENGTH_SHORT).show();
} else {
callback.unexpectedError(t);
}
}
});
}
});
}
@Override
public MyCall<T> clone() {
return new MyCallAdapter<>(call.clone(), callbackExecutor);
}
@Override
public boolean isExcute() {
return call.isExecuted();
}
}
}
这是我的配置添加自定义调用适配器
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addCallAdapterFactory(new ErrorHandlingAdapter.ErrorHandlingCallAdapterFactory()) // custom call adapter
.addConverterFactory(GsonConverterFactory.create())
.client(getHeader())
.build();
处理请求,例如:
@GET("api/getSomething")
ErrorHandlingAdapter.MyCall<BaseResponse> getSomething(@Query("param"),...)
处理回应:
ErrorHandlingAdapter.MyCall<BaseResponse> mCalls = ApiUtils.getSomething(...);
mCalls.enqueue(new ErrorHandlingAdapter.MyCallback<BaseResponse>() {
@Override
public void success(Response<BaseResponse> response) {
//handle response
}
@Override
public void unauthenticated(Response<?> response) {
//handle unauthenticated error
}
@Override
public void clientError(Response<?> response) {
//handle clientError error
}
@Override
public void serverError(Response<?> response) {
//handle serverError error
}
@Override
public void networkError(IOException e) {
//handle networkError error
}
@Override
public void unexpectedError(Throwable t) {
//handle unexpectedError error
}
}