Cómo crear el controller de respuesta genérica para el error y validar la respuesta utilizando retrofit, rxjava y dagger

Estoy intentando crear una architecture genérica para consumir la estructura compleja de json de la siguiente manera:

Formato Json

{ "type": "success", "code": "s-groups-0006", "description": "Index List successfully", "result": { "asOnDate": 1505457095278, "indexList": [ { "change": "22.35", "changePercent": "0.27", "isDefault": true, "isEditable": false } ] } 

}

Dagger Format

 @Singleton fun provideGson(): Gson = GsonBuilder() .setLenient() // .registerTypeAdapter(BaseResponse::class.java, RestDeserializer<BaseResponse<T>>()) .create() 

Rest Desolladores

  class RestDeserializer<T> : JsonDeserializer<T> { @Throws(JsonParseException::class) override fun deserialize(je: JsonElement, type: Type, jdc: JsonDeserializationContext): T? { val content = je.asJsonObject // Deserialize it. You use a new instance of Gson to avoid infinite recursion // to this deserializer return Gson().fromJson<T>(content, type) } 

}

Error de callback

 abstract class ErrorCallBack<T : BaseResponse<T>> : DisposableObserver<T>() { protected abstract fun onSuccess(t: T) override fun onNext(t: T) { //You can return StatusCodes of different cases from your API and handle it here. I usually include these cases on BaseResponse and iherit it from every Response onSuccess(t) } override fun onError(e: Throwable) { when (e) { is HttpException -> { val responseBody = (e).response().errorBody() responseBody?.let { Le("Error in call htttp exception") } } is SocketTimeoutException -> { // todo Le("Error in Socket time out") } is IOException -> { // todo Le("Error in IO Exception") } else -> { e.message?.let { // todo } } } } override fun onComplete() { } private fun getErrorMessage(responseBody: ResponseBody): String { return try { val jsonObject = JSONObject(responseBody.string()) jsonObject.getString("message") } catch (e: Exception) { e.message!! } } 

}

Repositorio

  override fun getValidateUser(validateUser: ValidateUser): LiveData<ValidateUserResponse> { val mutableLiveData = MutableLiveData<ValidateUserResponse>() remoteServices.requestValidateUser(validateUser) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(object : ErrorCallBack<BaseResponse<ValidateUserResponse>>() { override fun onSuccess(t: BaseResponse<ValidateUserResponse>) { if (t.type == CommonContents.SUCCESS) { Ld("Success in validate user") mutableLiveData.value = transform(t) } else { Le("Validate User Error") } } }) return mutableLiveData } 

Clase de datos

 data class BaseResponse<out T>( @SerializedName(CommonContents.TYPE) val type: String, @SerializedName(CommonContents.CODE) val Code: String, @SerializedName(CommonContents.DESCRIPTION) val Description: String, @SerializedName(CommonContents.RESULT)val result: T? = null) 

Estas son mis estructuras y trato de hacer una estructura genérica, pero estoy enfrentando un problema al invocar la callback de Error.

Por favor, guíame cómo lograr esto. ¿Puedo llamar al método genérico dentro de la respuesta genérica?

  .subscribeWith(object : ErrorCallBack<BaseResponse<ValidateUserResponse>>() { 

Guía para lograr código de trabajo

Esta es mi guía para hacer que algún código funcione. Se basa en los principios del desarrollo impulsado por testing .

  1. Configure su entorno de testing de unidad en su IDE. Personalmente, he estado usando JUnit 4 con Eclipse, pero es posible que prefiera JUnit 5 con el IDE de JetBrains.
  2. Escriba una testing unitaria para su constructor de la class ErrorCallback . Haz que pase. A continuación, escriba testings unitarias para cada uno de los methods, para ver si se comporta de la manera que espera.
  3. Escriba las testings unitarias donde su accesorio de testing es un PublishSubject<BaseResponse<Integer>> para algunos casos diferentes: datos normales, secuencia de datos normales, datos normales seguidos de error, datos normales seguidos de finalización.
  4. A partir de ahí, agregue algunas testings más para que pueda probar toda la cadena observable.
  • Sitio de Android con RxJava manejar resultado de consulta vacío
  • Asunto de RxJava: escuche el tipo diferente que el que emite
  • RxAndroid - Manejar errores con el operador Zip
  • Cómo contar el time de ejecución de lo observable
  • Cómo hacer que la function regrese Observable
  • Cambio observable a condición cumplida - RxJava2
  • Fusionar observables dependientes
  • Problema de encadenamiento Completable after flatMapCompletable
  • RxJava salida diferente entre Flowable y Observable con window y Groupby
  • Encadenando Observables para evitar suscripciones múltiples
  • ¿Cómo escalar dinámicamente el rebote de la stream de emisión de ráfagas?