如何在Retrofit与Kotlin中获取错误消息的响应体?
问题分析与解决方案
你当前的核心问题在于:外层的try-catch完全起不到作用——因为enqueue是异步调用,它仅负责发起请求,不会将请求过程中的异常抛出到当前线程的try块中,真正的错误分支要么是onResponse里的非成功响应,要么是onFailure里的网络/请求异常。
下面是改进后的代码,能完整获取服务器返回的具体错误信息:
api.uploadImage(imgId, requestBody).enqueue(object : Callback<Void> { override fun onResponse(call: Call<Void>, response: Response<Void>) { if (response.isSuccessful) { // 处理请求成功逻辑 } else { // 获取非2xx响应的错误体 response.errorBody()?.let { errorBody -> // 注意:errorBody.string()只能调用一次,流会被消耗 val errorDetail = errorBody.string() Log.i("tag", "上传失败,错误详情: $errorDetail") // 如果服务器返回JSON格式错误信息,可解析为自定义模型 // 示例:val errorModel = Gson().fromJson(errorDetail, ErrorModel::class.java) } ?: run { Log.i("tag", "上传失败,无可用错误信息") } } } override fun onFailure(call: Call<Void>, t: Throwable) { // 处理网络错误、超时、DNS解析失败等情况 Log.i("tag", "上传失败: ${t.message}") // 进一步区分异常类型,获取更精准信息 when(t) { is IOException -> Log.i("tag", "网络连接异常,请检查网络状态") is HttpException -> { val errorCode = t.code() val errorBody = t.response()?.errorBody()?.string() Log.i("tag", "HTTP错误码: $errorCode,错误详情: $errorBody") } else -> Log.i("tag", "未知错误: ${t.message}") } } })
关键说明
- 移除无用的外层
try-catch:异步请求的异常不会被这个try块捕获,完全是多余的。 errorBody()的使用注意:它的string()方法只能调用一次,因为输入流会被读取后关闭,如果需要多次使用,要先把结果保存到变量中。- 结构化错误解析:如果服务器返回的是JSON格式的错误(比如
{"code":1001,"msg":"图片格式不支持"}),可以用Gson、Moshi等序列化库将字符串解析为自定义的错误模型类,方便直接提取具体字段。
内容的提问来源于stack exchange,提问作者Paul S
相关产品推荐
相关产品推荐

