I am using retrofit:2.0.0-beta2 with RxJava and i cannot access the response body in the onError method of my subscriber.
Retrofit retrofit = new Retrofit
.Builder()
.baseUrl(ViatoService.baseUrl)
.client(client)
.validateEagerly()
.addConverterFactory(new ToStringConverterFactory())
.addConverterFactory(MoshiConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
In case of response code < 200 || code >= 300 (OkHttp handles redirects and so on) RxJavaCallAdapter will emit onError() with HttpException, HttpException contains response with body and other info.
There are three ways to construct your observable: Observable<BodyType>, Observable<Response<BodyType>>, or Observable<Result<BodyType>>. For the first version, there's nowhere to hang non-200 response information so it is included in the exception passed to onError. For the latter two, the data is encapsulated in the Response object and can be accessed by calling errorBody().
Hello.
I know that this post is old, but i Have a little problem, when I am getting the answer if I use ((HttpException) throwable).response().errorBody().string() and later I try to use the line again or assign to another variable, the second value is empty, anybody has been in the same situation?.
Thanks for your help.
@alejantab Once you consume the response body, you can't reuse it anymore. It's a normal behavior. Then store your response body (response().errorBody().string()) in a variable first, then reuse this variable.
public void onError(Throwable e){
HttpException error = (HttpException)e;
String errorBody = error.response().errorBody().string();
// now,you can do what you want to do ,like parse ....
}
Hope to help you!
If you want to separate Response Error and Exception, use Response<BaseResponse<String>>
So you can fetch your non 200 response with body in onNext, and exception in onError
Hi guys, i have very similar problem, can you check this question on stackoverflow: https://stackoverflow.com/questions/50945672/retrofit-response-codes-with-rxjava2
@fanjavaid can you please elaborate your version of the solution?
Will love to have a snippet for this. I still couldn't understand how will i manage to get my response body from API in case of an error as onError method only takes in a Throwable.
My server sends custom response in case of error such as
{
"status": "Failed",
"httpcode": 400,
"devMessage": "APICallSuccess",
"userMessage": "Problems with your input",
"data": {...}
}
I want to show the userMessage to the user while using Retrofit + RxJava.
Will love to have a snippet for this. I still couldn't understand how will i manage to get my response body from API in case of an error as onError method only takes in a Throwable.
My server sends custom response in case of error such as
{ "status": "Failed", "httpcode": 400, "devMessage": "APICallSuccess", "userMessage": "Problems with your input", "data": {...} }I want to show the userMessage to the user while using Retrofit + RxJava.
I want the same but i dont know how to catch response body in java
Sample:
Exception Class
`public class ExcepcionApi {
private int estado;
private String mensaje;
private int codigo;
public ExcepcionApi(int estado, String mensaje, int codigo){
this.estado = estado;
this.mensaje = mensaje;
this.codigo = codigo;
}
.......`
UserBean
`public class UsuarioBean {
@SerializedName("estado")
@Expose
private Integer estado;
@SerializedName("usuario")
@Expose
private Usuario usuario;`
........
The observer
`public DisposableObserver
return new DisposableObserver
` @Override `
` public void onNext(@NonNull Response loginResponse) {`
//HERE is SAVED THE ERROR RESPONSE.
ExcepcionApi excepcionApi = ExcepcionApi.fromResponseBody(loginResponse.errorBody());
Log.d("presenter", excepcionApi.getMensaje());
Most helpful comment
There are three ways to construct your observable:
Observable<BodyType>,Observable<Response<BodyType>>, orObservable<Result<BodyType>>. For the first version, there's nowhere to hang non-200 response information so it is included in the exception passed toonError. For the latter two, the data is encapsulated in theResponseobject and can be accessed by callingerrorBody().