使用Retrofit + Coroutine时如何获取服务器返回的错误体
How to get error body returned by server when using Retrofit + Coroutine
当使用 Coroutine 和 Retrofit 来调用网络 api 时,如果服务器 returns 出现错误(响应代码!= 200),我们将得到一个异常。我的问题是如何 find/read 服务器通过 Exception 发送的错误正文(在 Json 中)?
try{
apiService.login()
}catch(exception:Exception){
//How to read error body from exception
//Error body example: {"ok":false,"error":"Incorrect username or password."}
}
您只需要这样做:
(exception as? HttpException).response()?.errorBody()?.string()
这将return Json 格式的错误正文。
要处理协同程序和改造的错误,您必须创建一个密封的 class,按照以下步骤...
1:状态句柄Class
sealed class NetworkState {
data class Success(val data : CharactersResponseModel) : NetworkState()
object InvalidData : NetworkState()
data class Error(val error : String) : NetworkState()
data class NetworkException(val error : String) : NetworkState()
sealed class HttpErrors : NetworkState() {
data class ResourceForbidden(val exception: String) : HttpErrors()
data class ResourceNotFound(val exception: String) : HttpErrors()
data class InternalServerError(val exception: String) : HttpErrors()
data class BadGateWay(val exception: String) : HttpErrors()
data class ResourceRemoved(val exception: String) : HttpErrors()
data class RemovedResourceFound(val exception: String) : HttpErrors()
}
}
处理错误或成功API调用
private suspend fun fetchCharacters() : NetworkState {
return try {
val response = apiService.getCharacters()
if (response.isSuccessful) {
if (response != null) {
NetworkState.Success(response.body()!!)
} else {
NetworkState.InvalidData
}
} else {
when(response.code()) {
403 -> NetworkState.HttpErrors.ResourceForbidden(response.message())
404 -> NetworkState.HttpErrors.ResourceNotFound(response.message())
500 -> NetworkState.HttpErrors.InternalServerError(response.message())
502 -> NetworkState.HttpErrors.BadGateWay(response.message())
301 -> NetworkState.HttpErrors.ResourceRemoved(response.message())
302 -> NetworkState.HttpErrors.RemovedResourceFound(response.message())
else -> NetworkState.Error(response.message())
}
}
} catch (error : IOException) {
NetworkState.NetworkException(error.message!!)
}
}
在你的UI
中将 liveData 或 flow to Observer 设为 neworkState
当使用 Coroutine 和 Retrofit 来调用网络 api 时,如果服务器 returns 出现错误(响应代码!= 200),我们将得到一个异常。我的问题是如何 find/read 服务器通过 Exception 发送的错误正文(在 Json 中)?
try{
apiService.login()
}catch(exception:Exception){
//How to read error body from exception
//Error body example: {"ok":false,"error":"Incorrect username or password."}
}
您只需要这样做:
(exception as? HttpException).response()?.errorBody()?.string()
这将return Json 格式的错误正文。
要处理协同程序和改造的错误,您必须创建一个密封的 class,按照以下步骤...
1:状态句柄Class
sealed class NetworkState {
data class Success(val data : CharactersResponseModel) : NetworkState()
object InvalidData : NetworkState()
data class Error(val error : String) : NetworkState()
data class NetworkException(val error : String) : NetworkState()
sealed class HttpErrors : NetworkState() {
data class ResourceForbidden(val exception: String) : HttpErrors()
data class ResourceNotFound(val exception: String) : HttpErrors()
data class InternalServerError(val exception: String) : HttpErrors()
data class BadGateWay(val exception: String) : HttpErrors()
data class ResourceRemoved(val exception: String) : HttpErrors()
data class RemovedResourceFound(val exception: String) : HttpErrors()
}
}
处理错误或成功API调用
private suspend fun fetchCharacters() : NetworkState { return try { val response = apiService.getCharacters() if (response.isSuccessful) { if (response != null) { NetworkState.Success(response.body()!!) } else { NetworkState.InvalidData } } else { when(response.code()) { 403 -> NetworkState.HttpErrors.ResourceForbidden(response.message()) 404 -> NetworkState.HttpErrors.ResourceNotFound(response.message()) 500 -> NetworkState.HttpErrors.InternalServerError(response.message()) 502 -> NetworkState.HttpErrors.BadGateWay(response.message()) 301 -> NetworkState.HttpErrors.ResourceRemoved(response.message()) 302 -> NetworkState.HttpErrors.RemovedResourceFound(response.message()) else -> NetworkState.Error(response.message()) } } } catch (error : IOException) { NetworkState.NetworkException(error.message!!) }
}
在你的UI
中将 liveData 或 flow to Observer 设为 neworkState