I am using Retrofit 2.4.0, with GsonConverterFactory and RxJavaFactory.
Suppose I am now calling an API named getSomething
.
In normal situations, server returns
{
status: "ok",
errorMsg: "",
data: {...}
}
But if an error occurs:
{
status: "error",
errorMsg: "Some error message",
data: []
}
Note that data becomes an array if an error occurs.
This is how I define the API:
@GET("URL")
fun getSomething(): Observable<SomeResponse<SomeObject>>
SomeResponse:
open class SomeResponse<T> {
var data: T? = null
@SerializedName("errorMsg")
var errorMessage: String? = ""
var status: String? = ""
}
And in an APIManager
(Singleton):
fun getSomething(): Observable<SomeObject> {
return someAPI.getSomething()
.map{ response ->
if (response.status != "ok") throw new APIException(response.errorMessage)
response.data
}
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
As you can see, if status is not "ok"
, an APIException
which I defined by myself will be thrown with the error message returned from server, so that I can have my own handling (e.g. display a dialog with that error message).
But now it cannot even reach that throw.
Since data
is now an array, an JsonSyntaxException
is thrown instead, and therefore I cannot show the correct error message to user.
What I want to do
I know that I can delay the parsing of data
after I check the status, by making all declarations of Retrofit interface to return Observable<SomeResponse<Any>>
, and do:
.map{ response ->
if (response.status != "ok") throw new APIException(response.errorMessage)
response.data
}
.map{ data ->
//Parse the object here
}
Assume I don't want to do that, still relying on GsonConverterFactory to do the parsing, is there a way to throw APIException
with correct error message?