Reputation: 3
I have REST POST call create order as Observable<OrderResponse>
, when order create call is successful everything is fine, but then server returns error I get com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
because Gson does not know how to handle json that have different fields than my response model
Server error response:
[{
"code": 99,
"message": "Please check your request"
}]
OrderResponse
data class OrderResponse(
@Expose
var orderId: String,
@Expose
var redirectUrl: String,
@Expose
var validUntil: Long
)
RxJava subscription
repository.requestCreateNewOrder(newOrder)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<OrderResponse> {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
compositeDisposable.add(d)
}
override fun onNext(t: OrderResponse) {
}
override fun onError(t: Throwable) {
//HERE I GET JsonSyntaxException
}
})
Retrofit Service
interface OrderService {
@Headers(
"Content-Type: application/x-www-form-urlencoded ",
"Connection: Keep-Alive",
"Accept-Encoding: application/json",
"User-Agent: Fiddler"
)
@FormUrlEncoded
@POST("/createOrder")
fun createOrder(@Field("orderId") orderId: String,
@Field("payCurrency") payCurrency: String,
@Field("payAmount") payAmount: Double,
@Header("Content-Length") length: Int): Observable<OrderResponse>}
Anyone have any suggestions for how to pass retrofit or gson the error model to know how to handle it
Upvotes: 0
Views: 902
Reputation: 2852
As per your code you are only handling the success response
but you need to handle your error response too for this you need to ensure that your API should send you error codes different then 200 (success response generally greater then 200 and less then 300 i.e code >= 200 && code < 300 ) because retrofit consider 200-299 as success
You can achieve this simply by changing your observable return type to
Observable<Response< OrderResponse>>
and after receiving response from server simply check
if (orderResponse.isSuccessful()) {
//here you can handle success by using orderResponse.getbody()
} else {
// here you can display error message and if you further want
// to parse error response from server then use below function
errorOrderResponseHandling(orderResponse);
}
you want to further parse response into error model(in this example OrderAPIError is model class for error response) then below is the function
private void errorOrderResponseHandling(Response<OrderResponse> orderResponse) {
OrderAPIError orderAPIError = null;
try {
orderAPIError = new Gson().fromJson(String.valueOf(new
JSONObject(orderResponse.errorBody().string())), OrderAPIError.class);
// further orderAPIError object you can fetch server message and display
it to user as per your requirement
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Above example is in android not in kotlin but you can get idea and use function accordingly in kotlin
Upvotes: 0
Reputation: 2762
As you are using GSON to parse the JSON.
Your JSON sucessfull response will be something like
{
"orderId": 1,
"redirectUrl": "url",
"validUntil": 12414194
}
while for error response your JSON response start with Array.
[{
"code": 99,
"message": "Please check your request"
}]
So tell to server guy to not add the error response in Array [].
If you are getting the response as Array then you have to use list.
repository.requestCreateNewOrder(newOrder)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<List<OrderResponse>> {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
compositeDisposable.add(d)
}
override fun onNext(t: OrderResponse) {
}
override fun onError(t: Throwable) {
//HERE I GET JsonSyntaxException
}
})
In Observer response you have to add as List if your JSON response start with Array like error.
Solution : Correct it from backend for not adding Error Response in ARRAY.
Upvotes: 0