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.
  • El método de callback a menudo para reenviar el evento a Observable?
  • consultas de múltiples dominios de Android con RXJava
  • Ingrese los valores propios para combinarlos
  • Error "No se puede combinar Dex" al usar Room + Kotlin
  • ¿Por qué tengo un Log de salida no deseado al fusionar 2 observables en otro Observable, que los almacena temporalmente cada 10 segundos?
  • ¿Cómo continuar el procesamiento después de que ocurra un error en RxJava 2?
  • Enfrentando problemas con la implementación de Rx Java con la architecture de flujo en Android kotlin
  • ¿Cómo se usa Flowable.generate de Kotlin?
  • Inferencia de tipo Observable.combineLatest en kotlin
  • Room - SELECT query, get o default
  • Asunto de RxJava: escuche el tipo diferente que el que emite