Retrofit 2
имеет другую концепцию обработки "successful"
запросов, чем Retrofit 1
. В Retrofit 2
все requests
, которые могут быть выполнены (отправлены в API) и для которых вы получаете response
, рассматриваются как "successful"
. Это означает, что для этих requests
вызывается обратный вызов onResponse
, и вам нужно вручную проверить, действительно ли request
successful (status 200-299)
или erroneous (status 400-599)
.
Если запрос завершен successfully
,мы можем использовать response object
и делать все, что захотим. Если error
на самом деле failed (remember, status 400-599)
, мы хотим показать пользователю соответствующую информацию о проблеме.
Пример
Error Object
Предположим, ваш API отправляет JSON error body
следующим образом:
{
statusCode: 409,
message: "Email address already registered"
}
Примечание: вы можете увидеть JSON error body
, напечатав response.errorBody()
Чтобы избежать такого плохого взаимодействия с пользователем, мы сопоставляем тело ответа с объектом Java, представленным следующим классом.
class APIError {
private val statusCode:Int = 0
private val message:String
fun status():Int {
return statusCode
}
fun message():String {
return message
}
}
Error Handler
object ErrorUtils {
fun parseError(response:Response<*>):APIError {
val converter = ServiceGenerator.retrofit()
.responseBodyConverter(APIError::class.java, arrayOfNulls<Annotation>(0))
val error:APIError
try
{
error = converter.convert(response.errorBody())
}
catch (e:IOException) {
return APIError()
}
return error
}
}
Error Handler in Action
Теперь вы можете обрабатывать error
в API response
, используя ErrorUtils
, как показано ниже.
val call = service.me()
call.enqueue(object:Callback<User>() {
fun onResponse(call:Call<User>, response:Response<User>) {
if (response.isSuccessful())
{
// use response data and do some fancy stuff :)
}
else
{
// parse the response body …
val error = ErrorUtils.parseError(response)
// … and use it to show error information
// … or just log the issue like we’re doing :)
Log.d("error message", error.message())
}
}
fun onFailure(call:Call<User>, t:Throwable) {
// there is more than just a failing request (like: no internet connection)
}
})
Полный пример с видео приведен здесь retrofit-2-error-processing .