将自定义错误抛给Retrofit 2

时间:2017-05-22 08:08:43

标签: android rx-java retrofit2 moshi

我试图使用此代码段https://github.com/square/retrofit/issues/1497与Moshi一起使用自定义api错误。

API的回报是:

  • {"error":"message"}
  • {"failure":"message"}
  • {"success":"message"}
  • {...}
  • [{...},{...},...]

HTTP代码始终为200。

我的改造界面是:

public interface NewsService {

    /**
     * Get all news
     *
     * @return
     */
    @GET("getActualites.php")
    Observable<List<News>> loadNews();
}

所以我创建了泛型类:

public final class ApiResponse<T> {

    String failure;
    String error;
    String success;

    T data;

    public ApiResponse(String failure, String error, T data) {
        this.failure = failure;
        this.error = error;
        this.data = data;
    }

    public ApiResponse(T data) {
        this.data = data;
    }

    static class FailureException extends RuntimeException {

        public final String error;

        public FailureException(String error) {
            super("Error message : " + error.getMsg());
            this.error = error;
        }
    }

}

和转换器:

public class ApiErrorHandlerFactory extends Converter.Factory {

    public ApiErrorHandlerFactory() {
    }

    public static Converter.Factory create() {
        return new ApiErrorHandlerFactory();
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        Type envelopeType = Types.newParameterizedType(ApiResponse.class, type);
        return new ResponseEnvelopeConverter<>(retrofit.nextResponseBodyConverter(this, envelopeType, annotations));
    }

    private static class ResponseEnvelopeConverter<T> implements Converter<ResponseBody, T> {
        private final Converter<ResponseBody, ApiResponse<T>> delegate;

        ResponseEnvelopeConverter(Converter<ResponseBody, ApiResponse<T>> delegate) {
            this.delegate = delegate;
        }

        @Override
        public T convert(ResponseBody value) throws IOException {
            ApiResponse<T> envelope = delegate.convert(value);

            if (envelope.failure != null) {
                throw new ApiResponse.FailureException(envelope.failure);
            }
            if (envelope.error != null) {
                throw new ApiResponse.FailureException(envelope.error);
            }
            if (!TextUtils.isEmpty(envelope.success)) {
                Timber.d("Success response : %s", envelope.success);
            }

            return envelope.data;
        }
    }
}

当API返回错误/失败或成功时,这工作正常,但是当API返回数组时,它无法正常工作。

 com.squareup.moshi.JsonDataException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $
     at com.squareup.moshi.JsonUtf8Reader.beginObject(JsonUtf8Reader.java:140)
     at com.squareup.moshi.ClassJsonAdapter.fromJson(ClassJsonAdapter.java:155)
     at com.squareup.moshi.JsonAdapter$2.fromJson(JsonAdapter.java:127)
     at com.squareup.moshi.JsonAdapter.fromJson(JsonAdapter.java:34)
     at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:42)
     at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:25)
     at fr.mummyz.core.moshi.handler.ApiErrorHandlerFactory$ResponseEnvelopeConverter.convert(ApiErrorHandlerFactory.java:45)
     at fr.mummyz.core.moshi.handler.ApiErrorHandlerFactory$ResponseEnvelopeConverter.convert(ApiErrorHandlerFactory.java:36)
     at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:118)
     at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:212)
     at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)

我不知道为什么Moshi看到对象的泛型类型而不是数组

0 个答案:

没有答案