【问题标题】:How to handle both success and fail responses in Retrofit and RxJava2?如何在 Retrofit 和 RxJava2 中处理成功和失败响应?
【发布时间】:2018-11-18 07:02:11
【问题描述】:

我有以下要求:

@POST("devices/link/")
    fun linkDevice(
        @Body deviceInfo: DeviceInfo
    ): Single<Response<UserDevice>>

我想实现以下目标:

  1. 如果请求成功,获取 DeviceInfo 并根据状态代码向分析报告事件

  2. 如果请求失败,获取异常,转换并重新抛出。

所以,代码是:

fun linkDevice(): Single<UserDevice> {
    val deviceInfo = deviceUtil.getDeviceInfo()

    return devicesService
        .linkDevice(deviceInfo)
        .onErrorResumeNext { e ->
            val transformedException = transformRequestException(e) { httpException ->
                return@transformRequestException when (httpException.code()) {
                    409 -> DeviceAlreadyLinkedException()
                    else -> null
                }
            }
            Single.error(transformedException)
        }
        .flatMap { response ->
            if (response.isSuccessful) {
                val userDevice = response.body()

                userDevice?.let {
                    userPreferences.setDeviceId(it.id)
                }

                when (response.code()) {
                    200 -> {
                        // TODO: Analytics
                    }
                    201 -> {
                        // TODO: Analytics
                    }
                }

                Single.just(userDevice)
            } else {
                throw ApiException()
            }
        }
}

/**
 * Transform exception that came from request
 * By default, handles only network and HTTP 401 exceptions, but can contain custom logic, passed with specialTransformer
 */
fun transformRequestException(
    e: Throwable,
    specialTransformer: ((httpException: HttpException) -> Exception?)? = null
): Exception {
    return if (e is HttpException) {
        if (e.code() == 401) {
            NotAuthenticatedException()
        } else {
            specialTransformer?.invoke(e) ?: ApiException()
        }
    } else {
        NetworkException()
    }
}

但是这段代码不起作用,如果我使用 Response 对象进行操作,它将仅适用于我的改造服务中的Single&lt;UserDevice&gt;

但是,Single&lt;UserDevice&gt; 我无法获得 2XX 代码。

那么,如何实现期望的行为呢?

【问题讨论】:

  • 需要区分 200 和 201 吗?
  • @Blackbelt 200 表示现有设备已重新链接,201 表示新设备已链接。我需要将其传递给分析。
  • Single&lt;Result&lt;UserDevice&gt;&gt; 怎么样?
  • @EpicPandaForce Result 表示错误 == false 即使出现错误:(

标签: android kotlin retrofit2 rx-java2


【解决方案1】:

所以,就目前而言,我已经解决了以下问题:

data class RequestResult<T>(
    val data: T,
    val code: Int
)

fun <T> transformResponse(response: Response<T>): Single<RequestResult<T>> {
    if (response.isSuccessful) {
        return Single.just(RequestResult(response.body()!!, response.code()))
    } else {
        throw HttpException(response)
    }
}

fun <T> transformEmptyResponse(response: Response<T>): Completable {
    if (response.isSuccessful) {
        return Completable.complete()
    } else {
        throw HttpException(response)
    }
}

还有:

fun linkDevice(): Single<UserDevice> {
    val deviceInfo = deviceUtil.getDeviceInfo()

    return devicesService
        .linkDevice(deviceInfo)
        .flatMap { transformResponse(it) }
        .flatMap { requestResult ->
            requestResult.data.let { userDevice ->
                userPreferences.setDeviceId(userDevice.id)
                when (requestResult.code) {
                    200 -> {
                        // TODO: Analytics
                    }
                    201 -> {
                        // TODO: Analytics
                    }
                }

                Single.just(userDevice)
            }
        }
        .onErrorResumeNext { e ->
            val transformedException = transformRequestException(e) { httpException ->
                return@transformRequestException when (httpException.code()) {
                    409 -> DeviceAlreadyLinkedException()
                    else -> null
                }
            }
            Single.error(transformedException)
        }
}

看起来像 hack,但我没有找到更好的解决方案,而且它有效。

【讨论】:

    猜你喜欢
    • 2021-08-07
    • 2016-02-25
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多