NullReferenceException when calling ExecuteTaskAsync
See original GitHub issueI’m fighting with the TaskAsync
methods of RestSharp, and losing for now.
First, there seems to be a big inconsistency between the “standard” version of the Execute method and the asynchronous one.
I’ve tried this code:
// Connect to any non-existing IP address
var client = new RestClient("http://192.168.1.200:8001");
var request = new RestRequest("/")
{
RequestFormat = DataFormat.Json,
Method = Method.GET
};
var response = client.Execute(request);
The code works, I get no exception and the response has simply a ResponseStatus == Error
and the ErrorMessage
corresponding to the error (could not connect). So far so good.
Now, let’s try the same thing with the Async methods:
// Connect to any non-existing IP address
var client = new RestClient("http://192.168.1.200:8001");
var request = new RestRequest("/")
{
RequestFormat = DataFormat.Json,
Method = Method.GET
};
var response = await client.ExecuteTaskAsync(request);
I would expect the same behavior as the “standard” call, no exception and a ResponseStatus
in error. Except, I get a WebException
that is thrown because it couldn’t connect to the server.
OK, it’s inconsistent, but I can still work around that, I’ll catch the exception and manage it.
Now, let’s try to use the generic verison, ExecuteTaskAsync<T>
which parses the result into a class.
// Connect to any non-existing IP address
var client = new RestClient("http://192.168.1.200:8001");
var request = new RestRequest("/")
{
RequestFormat = DataFormat.Json,
Method = Method.GET
};
var response = await client.ExecuteTaskAsync<StupidClass>(request);
In that case, everything crashes and I get a NullReferenceException
coming from inside RestSharp’s code, seemingly from the DeserializeResponse
method. For some reason (the code being on another thread I guess) I cannot even catch it and it crashes the whole application.
Stack trace:
at RestSharp.RestClient.<>c__DisplayClass15`1.<ExecuteTaskAsync>b__12(IRestResponse`1 response, RestRequestAsyncHandle _)
at RestSharp.RestClient.DeserializeResponse[T](IRestRequest request, Action`2 callback, IRestResponse response, RestRequestAsyncHandle asyncHandle)
at RestSharp.RestClient.<>c__DisplayClassa`1.<ExecuteAsync>b__9(IRestResponse response, RestRequestAsyncHandle asyncHandle)
at RestSharp.RestClient.ProcessResponse(IRestRequest request, HttpResponse httpResponse, RestRequestAsyncHandle asyncHandle, Action`2 callback)
at RestSharp.RestClient.<>c__DisplayClass3.<ExecuteAsync>b__0(HttpResponse r)
at RestSharp.Http.ExecuteCallback(HttpResponse response, Action`1 callback)
at RestSharp.Http.ResponseCallback(IAsyncResult result, Action`1 callback)
at RestSharp.Http.<>c__DisplayClass3.<GetStyleMethodInternalAsync>b__1(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.HttpWebRequest.SetResponse(Exception E)
at System.Net.HttpWebRequest.SetAndOrProcessResponse(Object responseOrException)
at System.Net.ConnectionReturnResult.SetResponses(ConnectionReturnResult returnResult)
at System.Net.Connection.CompleteConnectionWrapper(Object request, Object state)
at System.Net.PooledStream.ConnectionCallback(Object owningObject, Exception e, Socket socket, IPAddress address)
at System.Net.ServicePoint.ConnectSocketCallback(IAsyncResult asyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.Socket.ConnectCallback()
at System.Net.Sockets.Socket.RegisteredWaitCallback(Object state, Boolean timedOut)
at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)
It might be two different bug, but I think both are quite important. There shouldn’t be inconsistency in the way the methods are used, either it should always return an exception in the case it cannot connect, or never throw an exception and have the status as Error. But it’s pretty bad that one throws an exception and the other passes.
Issue Analytics
- State:
- Created 9 years ago
- Comments:13 (2 by maintainers)
I tried the generic ExecuteTaskAsync route…heck I don’t even deserialize the response…and the exception is still un-catchable. Is there something else I can try? If I can’t get this to work it’s a deal breaker. I can’t have the application bombing over a simple exception - I’d have to switch to another library.
Temporarily fixed that by using non-generic method and Json.Net deserializer:
IRestResponse response = await _client.ExecuteTaskAsync(request); var data = JsonConvert.DeserializeObject<Subscription>(response.Content);