You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Retrofit Gson Converter时Kotlin空安全失效问题排查

服务器返回非预期200响应时,Kotlin非空字段为何未抛出异常导致崩溃

服务器在短信验证码无效时返回200状态码(本应返回4xx错误码),但我的Android代码未捕获到空值问题,最终UI/ViewModel层拿到Result.Success(null)并崩溃——所有字段均定义为非空String,未使用String?。近期刚将Kotlin从1.8.*升级至1.9.0,这是否是问题根源?

数据源层代码

override suspend fun forgotPasswordCheckCode(phone: String, code: String): String {
    return try {
        authApi.forgotPasswordCheckCode(
            NetworkForgotPasswordCheckCodeRequest(
                phone = phone,
                code = code
            )
        ).data.verificationToken
    } catch (e: Throwable) {
        throw ... // 解析HTTP错误的逻辑,但此处未捕获到异常
    }
}

仓库层代码

override fun forgotPasswordCheckCode(phone: String, code: String): Flow<String> = flow {
    val token = authDataSource.forgotPasswordCheckCode(phone, code)
    emit(token)
}

领域层用例的包装逻辑

inline fun <reified T> Flow<T>.wrapAsResult(): Flow<Result<T>> {
    return this
        .map<T, Result<T>> {
            Result.Success(it)
        }
        .onStart { emit(Result.Loading) }
        .catch { error ->
            Timber.e(error, "Flow")
            emit(Result.Error(error))
        }
}

序列化实体类

data class NetworkForgotPasswordCheck(
    @SerializedName("verificationToken")
    val verificationToken: String,
)

data class NetworkDataResponse<T>(@SerializedName("data") val data: T)

Retrofit接口定义

@POST("Auth/verify/sms/password/complete")
suspend fun forgotPasswordCheckCode(
    @Body checkCodeRequest: NetworkForgotPasswordCheckCodeRequest
): NetworkDataResponse<NetworkForgotPasswordCheck>

服务器返回示例

<-- 200 https://.../Auth/verify/sms/password/complete (84ms)
{"data":{"message":"Unable to verify subject with given code"}}

依赖版本

[versions]
kotlin = "1.9.0"
okhttpBom = "4.10.0"
retrofit = "2.9.0"

内容的提问来源于stack exchange,提问作者user924

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 12:52:46