Retrofit OnFailure场景下无法获取API错误消息问题求助
问题解决:API返回200+isSuccess=false却进入OnFailure回调
问题核心
API返回状态码200、isSuccess=false且包含业务错误消息,但代码触发了Retrofit的OnFailure回调,最终data为null,进入else分支,无法展示指定提示。
原因分析
- JSON解析异常:API失败时
response字段返回字符串"Error",但BaseResponse<PartsDetailsResponse>中response字段定义为非空的PartsDetailsResponse类型,类型不匹配导致Gson解析失败,触发OnFailure。 - Repository逻辑错误:当前
BaseRepository仅在网络请求成功时发送Resource.success,未区分业务逻辑的成功/失败,也未正确传递解析后的完整响应体。
解决方案
1. 修复BaseResponse模型,兼容解析
修改BaseResponse,让response字段可空,并添加未知字段忽略,避免解析失败:
import com.google.gson.annotations.JsonIgnoreProperties @JsonIgnoreProperties(ignoreUnknown = true) data class BaseResponse<T>( val isSuccess: Boolean, val message: String?, val response: T? // 改为可空,兼容失败时的字符串/空值 )
2. 调整BaseRepository的回调逻辑
网络请求返回200即视为请求成功,将完整响应体传递给上层,由上层处理业务逻辑的isSuccess:
override fun onResponse(call: Call<BaseResponse<T>>, response: Response<BaseResponse<T>>) { if (response.isSuccessful) { val body = response.body() if (body != null) { // 网络请求成功,无论业务isSuccess是true/false,都传递完整数据 responseData.value = Resource.success(body) println("getCallBack::::${response.code()}") } else { responseData.value = Resource.error("Empty response body", null) } } else { println("getCallBack${response.code()}") responseData.value = Resource.error("Request failed with code: ${response.code()}", null) } }
3. 优化观察者逻辑,分层判断
先判断网络请求状态,再处理业务逻辑的isSuccess:
productDetailEtaVM.partsDetailsData.observe(viewLifecycleOwner, Observer { resource -> dismissProgressBar() when(resource.status) { Status.SUCCESS -> { resource.data?.let { baseResponse -> when(baseResponse.isSuccess) { true -> { // 业务成功逻辑 } false -> { putToast(baseResponse.message ?: "Unknown business error") } } } ?: run { putToast("Empty response data") } } Status.ERROR -> { putToast(resource.message ?: "Request failed") } Status.LOADING -> { // 加载状态处理(按需调整) } } })
效果验证
修改后,API返回200+isSuccess=false时:
- 解析不会失败,进入
onResponse回调 Resource携带完整的BaseResponse数据- 观察者会进入业务失败分支,弹出指定提示信息
内容的提问来源于stack exchange,提问作者Sumit Vishwakarma
相关产品推荐
相关产品推荐

