You can create a result data class like this
data class ApiResult<out T>(
val status: Status,
val data: T?,
val error: Throwable?,
val message: String?
) {
enum class Status {
SUCCESS,
ERROR,
LOADING
}
companion object {
fun <T> success(data: T?): ApiResult<T> {
return ApiResult(Status.SUCCESS, data, null, null)
}
fun <T> error(message: String, error: Throwable?): ApiResult<T> {
return ApiResult(Status.ERROR, null, error, message)
}
fun <T> loading(data: T? = null): ApiResult<T> {
return ApiResult(Status.LOADING, data, null, null)
}
}
override fun toString(): String {
return "Result(status=$status, data=$data, error=$error, message=$message)"
}
}
and then create your custom base response like this
data class CommonResponse<T>(
@SerializedName("error") val error: Boolean,
@SerializedName("status") val status: Int,
@SerializedName("message") val message: String?,
@SerializedName("response") val response: T?
)
and assign them like this in retrofit
suspend fun <T> getResponse(
request: suspend () -> Response<T>
): ApiResult<T> {
return try {
val result = request.invoke()
if (result.isSuccessful) {
return ApiResult.success(result.body())
} else {
ApiResult.error("Error", null)
}
} catch (e: Throwable) {
ApiResult.error("Unkown Error", e)
}
}
and use them like this in call
interface CheckWhereApi {
//Check Where API
@GET("url")
suspend fun checkWhere(): Response<CommonResponse<MyModel>>
}