refit: How to handle Failure while connecting to API
How to I handle can’t connect to the API exception.
Currently my app crashes due to the following exception not been handled.
{System.Net.WebException: Error: ConnectFailure (Connection refused) ---> System.Net.Sockets.SocketException: Connection refused
at System.Net.Sockets.Socket.Connect (System.Net.EndPoint remoteEP) [0x000cb] in /Users/builder/data/lanes/3415/7db2aac3/source/mono/mcs/class/System/System.Net.Sockets/Socket.cs:1313
at System.Net.WebConnection.Connect (System.Net.HttpWebRequest request) [0x0019b] in /Users/builder/data/lanes/3415/7db2aac3/source/mono/mcs/class/System/System.Net/WebConnection.cs:195
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetRequestStream (IAsyncResult asyncResult) [0x00043] in /Users/builder/data/lanes/3415/7db2aac3/source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:882
at System.Threading.Tasks.TaskFactory`1[TResult].FromAsyncCoreLogic (IAsyncResult iar, System.Func`2 endFunction, System.Action`1 endAction, System.Threading.Tasks.Task`1 promise, Boolean requiresSynchronization) [0x00014] in /Users/builder/data/lanes/3415/7db2aac3/source/mono/external/referencesource/mscorlib/system/threading/Tasks/FutureFactory.cs:550
--- End of stack trace from previous location where exception was thrown ---
This is my API Interface
public interface IUserService
{
[Post("/Account/Authenticate")]
Task<User> Authenticate([Body] User user);
}
Then this is how I initialize and call the service
var _userService = RestService.For<IUserService>("http://192.168.0.100:44314/api");
user = await _userService.Authenticate(user);
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 21 (4 by maintainers)
This has been on my radar for a while. We should probably split
ApiException
intoApiRequestException
andApiResponseException
that derive from a common base. We’re not handling request exceptions (e.g. dns errors, etc) at all at the moment, which is why you get the rawWebException
.A workaround in the meantime (if using C#6) is:
I’ve actually used something similar to deal with retries for transient errors (this was before I knew about Polly):
Is there a way to not throw an exception ? I mean, this will dramatically kill performances. Besides, it’s not really an exception since we got a response. An exception would be the server not responding at all.
There are two different things going on though…semantically, they are different exceptions. The
ApiException
is for when the API itself is throwing andWebException
is when the wire/server/network itself is the issue. I’m not sure it really makes sense to combine them as you’d typically want to take different actions based on those.For
WebException
you may want to retry a few times. For anApiException
you’d likely simply fail.I still don’t get it why this library is throwing
ApiException
when status code is not successful. I agree with @oooolivierrrr - you got actual response so why treat it as exception? I’m returning e.g.BadRequest
respones from the api that are already wrapped into customWebApiResponse
that contains some extras that I may use on the client and if I want to not deal with exceptions in my case I would need to define my api client as:Task<ApiResponse<WebApiResponse<User>>> Authenticate([Body] User user);
which is hilarious and wrapping client calls with try catch is out of option because this is not a valid solution and just a hacky way to make it actually work.