Closed jemshit closed 8 years ago
I have found this solution, i am not sure if it good solution. It converts errorBody
to String:
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(response.errorBody().byteStream()));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
String finallyError = sb.toString();
I've managed to do this with also Converter
now. I think this is better solution. This is error returned from server:
"Message": "Authorization has been denied for this request."
I have this class for modeling this error:
public class ModelError {
private String Message;
public String getMessage() {
return Message;
}
public void setMessage(String Message) {
this.Message = Message;
}
}
And this is code for getting error message from response.errorBody()
:
@Override
public void onResponse(Response<MyCustomModel> response, Retrofit retrofit) {
if (response.errorBody() != null ) {
Converter<ResponseBody, ModelError> errorConverter =
retrofit.responseConverter(ModelError.class, new Annotation[0]);
try {
ModelError error = errorConverter.convert(response.errorBody());
} catch (IOException e) {
e.printStackTrace();
}
// Now use error.getMessage()
}
...
}
Is there a new / better solution for this? The current retrofit2 snapshot does not provide Retrofit retrofit
in the onResponse
Callback anymore :(
responseConverter is now responseBodyConverter
Update: Working for retrofit2
if (response.isSuccess()) {
// everything ok
} else {
Converter<ResponseBody, ErrorResponse> converter = mApp.getRetrofit().responseBodyConverter(ErrorResponse.class, new Annotation[0]);
try {
ErrorResponse errors = converter.convert(response.errorBody());
Toast.makeText(this, errors.getMessage(), Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, R.string.error_server_error, Toast.LENGTH_LONG).show();
}
}
You need to pass around the Retrofit or the Converter instance yourself.
On Tue, Dec 15, 2015, 5:41 AM Philip Giuliani notifications@github.com wrote:
Is there a new solution for this? The current retrofit2 snapshot does not provide Retrofit retrofit in the onResponse Callback anymore :(
— Reply to this email directly or view it on GitHub https://github.com/square/retrofit/issues/1321#issuecomment-164722592.
@JakeWharton , is it possible to covert to List
Type listOfString = new TypeToken<List<String>>() {}.getType();
I found a better way to convert errorbody to JSONObject if you dont have time for creating ResponseError classes. Just do
JSONObject jObjError = new JSONObject (response.errorBody().string())
No silly converter required, no bufferedreader, plain old JSONObject as ususal
How about if errorBody contains only a string?
Just call .string()
on it then
@meetmkjangid Strangely, if you call response.errorBody().string()
twice, the second time it returns empty.
Eg:
LoggerUtils.d(AppConstants.DEBUG_TAG, "Response first- " + response.errorBody().string());
LoggerUtils.d(AppConstants.DEBUG_TAG, "Response second - " + response.errorBody().string());
**Response**
D/Log: Response before- {"status":"error","code":"ERR037","message":"Incorrect Code"}
D/Log: Response after -
That's not strange, that's how a ResponseBody works. It's a resource you read.
On Mon, Oct 3, 2016, 6:46 PM RmK notifications@github.com wrote:
@meetmkjangid https://github.com/meetmkjangid Strangely, if you call response.errorBody().string() twice, (one inside log and one for parsing the data), the second time it returns empty.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/1321#issuecomment-251159005, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEESSDyOHC-y_GeoX5H5ZEztb_y5N0ks5qwTF8gaJpZM4GpCxz .
Thanks @JakeWharton . My understanding was that it could be read any number of times. I guess that's not possible.
@philipgiuliani should i create ErrorResponse class as a POJO or POJO with Gson Annotations . It works like a Charm @philipgiuliani .Love you dude
I am migrating from retrofit1 and missing RetrofitError is like a nightmare. How do I rewrite this code?
public static Optional <JsonObject> getErrorMessage(Throwable e){
if(RetrofitError.class.isInstance(e)){
RetrofitError err = RetrofitError.class.cast(e);
Object responce = err.getBody();
if(JsonObject.class.isInstance(responce)){
JsonObject res = JsonObject.class.cast(responce);
return Optional.of(res);
} else {
return Optional.absent();
}
} else {
return Optional.absent();
}
}
The error API of 1st version was great.....
Any one help me to how to handle this type error in retrofit?? [ { "error": { "field": "data.first_name", "message": "must be first_name format" }, "message": "Alphabet characters are allowed in name." }, { "error": { "field": "data.first_name", "message": "must be first_name format" }, "message": "Alphabet characters are allowed in name." } ]
Convert response.errorBody().string()
to an array of your custom model. Use Gson or any other (de)serialization library for the conversion.
Share the StackOverflow link, I will provide the sample code.
What about Dagger2? I think this "mApp.getRetrofit()" realization is not good. And Use GSON in each method not good too. Now I use my custom RestResponse class.
@Data
public class RestResponse<T> {
private RestError error;
private T response;
@Data
public static class RestError {
private int code;
private String message;
}
}
Adn get error:
response.getError()
in onSuccess
:
@Override
public void onSuccess(RestResponse<PaymentResponse> response) {
if (response.getError() != null) {
RestResponse.RestError error = response.getError();
if (error.getCode() == 999999) {
..............
And I do not understand what is the point retrofit2 Response
? can there be a normal nice way to convert an error into an object?
Why Call\<Entity> does not work when code is non-20x?
Claps for @mkjangid answer, .string()
is make life easier.
Why don't you ask yourself, we use library to make dev life easier, but why it's not be implemented from the start or just need to create stupid converter to see the plain text we want in its whole context.
if the server doesn't returns anything (obstacle like: you have no access to backend/3rd-party error, etc), and the errorBody()
null or just empty,
If you did this
JSONObject jObjError = new JSONObject (response.errorBody().string())
it will throws: JSONException: Value of type java.lang.String cannot be converted to JSONObject
see answer:
new JSONObject("{your string}")
what is mApp?
if the server doesn't returns anything (obstacle like: you have no access to backend/3rd-party error, etc), and the
errorBody()
null or just empty,If you did this
JSONObject jObjError = new JSONObject (response.errorBody().string())
it will throws:
JSONException: Value of type java.lang.String cannot be converted to JSONObject
You could just wrap this in a try/catch block. It's good practice anyways.
help solve an error in this code
class LoginViewModel:ViewModel() {
val logRepo= LoginRepository()
val logLiveData=MutableLiveData
fun loginUser(loginRequest: LoginRequest) {
viewModelScope.launch {
val response = logRepo.login(loginRequest)
if (response.isSuccessful) {
} else {
val errorBody = response.errorBody()?.string() ?: "Unknown error" // Get the error message from the error response or use a default message if null
errLiveData.postValue(errorBody)
}
}
}
}
Can somebody provide example of converting
response.errorBody()
to some Error class or String or JSON ? I've tried this kind of converter and this approach, but i always getnull
?In my case server responds with