如何在Retrofit中动态处理错误

huangapple go评论67阅读模式
英文:

How to handle errors dynamically in Retrofit

问题

在我的应用程序中,我使用了Retrofit库来连接服务器,有时会因验证或其他原因显示错误...<br>
错误消息的格式如下:<br>

{
  "message": "The given data was invalid.",
  "errors": {
    "login": [
      "Email or phone is not valid"
    ]
  }
}

login对象在其他API中可能会更改,也许会显示passwordbasket或其他... <br>
我知道我可以使用上述的JSON创建错误类,并使用Gson库将errorBody转换并显示出来!<br>
但我不想为每个API创建一个新类!<br>
我想创建一个通用类,从Jsonerrors字段中获取所有错误消息并显示给用户!<br>

我的NetworkResponse类:<br>

open class NetworkResponse<T>(private val response: Response<T>) {

    fun generalNetworkResponse(): NetworkRequest<T> {
        return when {
            response.code() == 401 -> NetworkRequest.Error("You are not authorized")
            response.code() == 422 -> NetworkRequest.Error("Api key not found!")
            response.code() == 500 -> NetworkRequest.Error("Try again")
            response.isSuccessful -> NetworkRequest.Success(response.body()!!)
            else -> NetworkRequest.Error(response.message())
        }
    }
}

我如何使用Retrofit动态处理错误?

英文:

In my application I used Retrofit library for connect to server and some time show me error for validation or other reasons ... <br>
Error message format has such as below: <br>

{
  &quot;message&quot;: &quot;The given data was invalid.&quot;,
  &quot;errors&quot;: {
    &quot;login&quot;: [
      &quot;Email or phone is not valid&quot;
    ]
  }
}

login object is change in other API and perhaps show password, basket or other... <br>
I Know I can create error class with above Json and with Gson library convert errorBody and show it! <br>
But I don't want to create a new class for each API ! <br>
I want create one general class and get all of errors messages from errors field of Json and show it to user! <br>

My NetworkResponse class: <br>

open class NetworkResponse&lt;T&gt;(private val response: Response&lt;T&gt;) {

    fun generalNetworkResponse(): NetworkRequest&lt;T&gt; {
        return when {
            response.code() == 401 -&gt; NetworkRequest.Error(&quot;You are not authorized&quot;)
            response.code() == 422 -&gt; NetworkRequest.Error(&quot;Api key not found!&quot;)
            response.code() == 500 -&gt; NetworkRequest.Error(&quot;Try again&quot;)
            response.isSuccessful -&gt; NetworkRequest.Success(response.body()!!)
            else -&gt; NetworkRequest.Error(response.message())
        }
    }
}

How can I handle dynamically errors with Retrofit?

答案1

得分: 2

Create a class named ApiError

data class ApiError(
    val message: String?,
    val errors: Map<String, List<String>>?
)

In your Retrofit Callback implementation, you can use the Gson library to parse the error response into an instance of ApiError. Here's an example:


class MyCallback : Callback<MyResponse> {

    override fun onResponse(call: Call<MyResponse>, response: Response<MyResponse>) {
        // handle success response...
    }

    override fun onFailure(call: Call<MyResponse>, t: Throwable) {
        // handle network error...
    }

    override fun onFailure(call: Call<MyResponse>, response: Response<MyResponse>) {
        if (response.errorBody() != null) {
            try {
                val apiError = Gson().fromJson(response.errorBody()!!.string(), ApiError::class.java)
                // handle API error...
                val errorMessage = apiError.message
                val errors = apiError.errors
                // You can iterate through the map of errors and display them to the user
                errors?.forEach { (field, fieldErrors) ->
                    // display field errors to user
                }
            } catch (e: IOException) {
                // handle parsing error...
            }
        } else {
            // handle unexpected error...
        }
    }
}
英文:

Create a class named ApiError

data class ApiError(
    val message: String?,
    val errors: Map&lt;String, List&lt;String&gt;&gt;?
)

In your Retrofit Callback implementation, you can use the Gson library to parse the error response into an instance of ApiError. Here's an example:


class MyCallback : Callback&lt;MyResponse&gt; {

    override fun onResponse(call: Call&lt;MyResponse&gt;, response: Response&lt;MyResponse&gt;) {
        // handle success response...
    }

    override fun onFailure(call: Call&lt;MyResponse&gt;, t: Throwable) {
        // handle network error...
    }

    override fun onFailure(call: Call&lt;MyResponse&gt;, response: Response&lt;MyResponse&gt;) {
        if (response.errorBody() != null) {
            try {
                val apiError = Gson().fromJson(response.errorBody()!!.string(), ApiError::class.java)
                // handle API error...
                val errorMessage = apiError.message
                val errors = apiError.errors
                // You can iterate through the map of errors and display them to the user
                errors?.forEach { (field, fieldErrors) -&gt;
                    // display field errors to user
                }
            } catch (e: IOException) {
                // handle parsing error...
            }
        } else {
            // handle unexpected error...
        }
    }
}

huangapple
  • 本文由 发表于 2023年4月11日 02:12:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75979592.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定