How to handle errors with Retrofit?

╄→гoц情女王★ 提交于 2019-12-12 07:07:54

问题


My server returns a basic JSON structure for all request like:

{  
    "success": false,
    "data": {  
        "errors": {  
            "email": [  
                "This is not an email."
            ],
            "password": [  
                "The password must be at least 6 characters."
            ]
        }
    }
}

Where success can be true or false, and data can return a number of things, from errors to data the app might need.

How can I handle this response (both success and error) using Retrofit?

What would need to be changed/added to my Retrofit API call?

Call<BasicResponse> call = apiService.login(emailString, passwordString);
call.enqueue(new Callback<BasicResponse>() {
    @Override
    public void onResponse(Call<BasicResponse> call, Response<BasicResponse> response) {
        //
    }

    @Override
    public void onFailure(Call<BasicResponse> call, Throwable t) {
        //
    }
});

回答1:


Essentially you'll want to work with your models. You have a couple of options here, but in the end it comes down to the response code of your api and how you structure your models.

Let's get the models out of the way first. One way you can deal with the object having an error or not is by including this as a field of your models. Say you have the error object:

public class Errors {
  // ...
}

This represents the errors object in your json:

"errors": {  
        "email": [  
            "This is not an email."
        ],
        "password": [  
            "The password must be at least 6 characters."
        ]
    }

Now say you have a data object to represent the json object:

"data": {  
    "errors": {  
        "email": [  
            "This is not an email."
        ],
        "password": [  
            "The password must be at least 6 characters."
        ]
    }
}

You can simply have:

public class Data {
   @SerializedName("success")
   @Expose
   private boolean success;
   @SerializedName("errors")
   @Expose
   private Errors errors;
   // Here you can then add other models, i.e:
   // @SerializedName("user")
   // @Expose
   // private User user;
 }

As you can see, you can then add the rest of the models to the Data object. When the response is successful, errors will be null and success true. When the response is unsuccessful you'll have the opposite scenario. You can check this answer for more details and other ways to achieve this.

Now to the part where you handle the error response.

If your call succeeds you'll end up in the onResponse call. This means that you'll have to check the value of Data.success before you can start interacting with your objects. If false you know you can access the errors field without producing a NullPointerException and if true you know you have the data correctly retrieved.

onFailure is only called when there's an exception in example socket timeout or serialising and deserialising the request.




回答2:


this is what you need Retrobomb, you can create a model with a list errors.

From server you can return a 422 Exception

@RetrobombMappings(
  ErrorMapping(code = 422, errorType =  ErrorMap::class)
)
@Headers("Content-Type: application/json")
@POST("/endpoint")
fun createFoo(@Body params: Map<String, String>): Completable


data class ErrorMap(@SerializedName("errors") val errors: ErrorMap.Error){

    class Error(@SerializedName("email") val email: List<String>?,
                @SerializedName("password") val password : List<String>?)

}

Errors will be easy to handle.



来源:https://stackoverflow.com/questions/41539217/how-to-handle-errors-with-retrofit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!