I am using Retrofit to connect to a user configurable URL, the issue I am having is how to handle a blank URL. As expected the RestAdapter.Builder throws an IllegalArgumentException when the server is null/blank, which means it is not possible to call create to generate the retrofit interface, leaving me with a null interface.
For example using the following API interface;
interface IApiService {
@POST("/{path}/api/{userid}/calls/Action")
void startCall(@Path("path") String path, @Path("userid") String userid, @Body Action action, Callback<Response> callback);
@PUT("/{path}/api/{userid}/calls/Action")
void addToCall(@Path("path") String path, @Path("userid") String userid, @Body Action action, Callback<Response> callback);
}
I have created a wrapper class for the Retrofit interface as the callback type is a Retrofit Callback, and I wish to be able to swap this out if needed.
public class ApiServiceWrapper implements IAPiServiceWrapper {
private IApiService mAPiService;
@Inject
ApiServiceWrapper(Settings settings, RequestInterceptor requestInterceptor) {
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer(settings.getUrl())
.setRequestInterceptor(requestInterceptor)
.setConverter(new ActionConverter())
.build();
mAPiService = restAdapter.create(IApiService.class);
}
public void startCall(String path, String userid, Action action, final IApiResultCallback<Response> callback) {
mAPiService.startCall(path, userid, action, new Callback<Response>() {
@Override
public void success(Response response, Response response2) {
callback.success();
}
@Override
public void failure(RetrofitError error) {
callback.failure(error.getResponse().getReason());
}
});
}
public void addToCall(String path, String userid, Action action, final IApiResultCallback<Response> callback) {
mAPiService.addToCall(path, userid, action, new Callback<Response>() {
@Override
public void success(Response response, Response response2) {
callback.success();
}
@Override
public void failure(RetrofitError error) {
callback.failure(error.getResponse().getReason());
}
});
}
}
So how should I handle an Exception thrown by the RestAdapter.Builder?
In my eyes it seems sensible to check if the settings.getUrl() returns a valid URL, if it does then populate the interface with Retrofit. But how do I handle the case when the URL is empty, one solution would be to check for null, eg;
public void startCall(String path, String userid, Action action, final IApiResultCallback<Response> callback) {
if (mAPiService != null) {
mAPiService.startCall(path, userid, action, new Callback<Response>() {
@Override
public void success(Response response, Response response2) {
callback.success();
}
@Override
public void failure(RetrofitError error) {
callback.failure(error.getResponse().getReason());
}
});
} else {
callback.failure("Some reason here :D");
}
}
This works but my API interfaces are quite big and I would rather not have to check for null on every call.
What would be nice is if I could set the mAPiService to an invalid implementation which instantly just calls failure with a message, for example;
@Inject
ApiServiceWrapper(Settings settings, RequestInterceptor requestInterceptor) {
if (TextUtils.isEmpty(settings.getUrl())) {
mAPiService = new InvalidSettingsApiService("some error")
} else {
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer(settings.getUrl())
.setRequestInterceptor(requestInterceptor)
.setConverter(new ActionConverter())
.build();
mAPiService = restAdapter.create(IApiService.class);
}
}
But this is not possible as the IApiService interface uses the Retrofit Callback interface which requires a failure parameter of RetrofitError.
Are any of the options I have listed ok? or is there a better solution to handling the case of not being able to generate the interface?