diff --git a/RestSharp.IntegrationTests/AsyncTests.cs b/RestSharp.IntegrationTests/AsyncTests.cs index 977c0fb69..37ee102e6 100644 --- a/RestSharp.IntegrationTests/AsyncTests.cs +++ b/RestSharp.IntegrationTests/AsyncTests.cs @@ -87,30 +87,16 @@ public void Can_Handle_Exception_Thrown_By_OnBeforeDeserialization_Handler() var client = new RestClient(baseUrl); var request = new RestRequest("success"); - request.OnBeforeDeserialization += response => + request.OnBeforeDeserialization += r => { throw new Exception(ExceptionMessage); }; var task = client.ExecuteTaskAsync(request); - - try - { - // In the broken version of the code, an exception thrown in OnBeforeDeserialization causes the task to - // never complete. In order to test that condition, we'll wait for 5 seconds for the task to complete. - // Since we're connecting to a local server, if the task hasn't completed in 5 seconds, it's safe to assume - // that it will never complete. - Assert.True(task.Wait(TimeSpan.FromSeconds(5)), - "It looks like the async task is stuck and is never going to complete."); - } - catch (AggregateException e) - { - Assert.Equal(1, e.InnerExceptions.Count); - Assert.Equal(ExceptionMessage, e.InnerExceptions.First().Message); - return; - } - - Assert.True(false, "The exception thrown from OnBeforeDeserialization should have bubbled up."); + task.Wait(); + var response = task.Result; + Assert.Equal(ExceptionMessage, response.ErrorMessage); + Assert.Equal(ResponseStatus.Error, response.ResponseStatus); } } @@ -233,15 +219,12 @@ public void Can_Timeout_GET_TaskAsync() //Half the value of ResponseHandler.Timeout request.Timeout = 500; - AggregateException agg = Assert.Throws( - delegate - { - var task = client.ExecuteTaskAsync(request); - task.Wait(); - }); - Assert.IsType(typeof(WebException), agg.InnerException); - Assert.Equal("The request timed-out.", agg.InnerException.Message); + var task = client.ExecuteTaskAsync(request); + task.Wait(); + var response = task.Result; + Assert.Equal(ResponseStatus.TimedOut, response.ResponseStatus); + } } @@ -258,15 +241,10 @@ public void Can_Timeout_PUT_TaskAsync() //Half the value of ResponseHandler.Timeout request.Timeout = 500; - AggregateException agg = Assert.Throws( - delegate - { - var task = client.ExecuteTaskAsync(request); - task.Wait(); - }); - - Assert.IsType(typeof(WebException), agg.InnerException); - Assert.Equal("The request timed-out.", agg.InnerException.Message); + var task = client.ExecuteTaskAsync(request); + task.Wait(); + var response = task.Result; + Assert.Equal(ResponseStatus.TimedOut, response.ResponseStatus); } } diff --git a/RestSharp.IntegrationTests/NonProtocolExceptionHandlingTests.cs b/RestSharp.IntegrationTests/NonProtocolExceptionHandlingTests.cs index e90407fae..527661155 100644 --- a/RestSharp.IntegrationTests/NonProtocolExceptionHandlingTests.cs +++ b/RestSharp.IntegrationTests/NonProtocolExceptionHandlingTests.cs @@ -37,22 +37,14 @@ public void Task_Handles_Non_Existent_Domain() Method = Method.GET }; - AggregateException agg = Assert.Throws( - delegate - { - var response = client.ExecuteTaskAsync(request); + var task = client.ExecuteTaskAsync(request); + task.Wait(); - response.Wait(); - }); + var response = task.Result; - Assert.IsType(typeof(WebException), agg.InnerException); - Assert.Equal("Unable to connect to the remote server", agg.InnerException.Message); - - //var client = new RestClient("http://nonexistantdomainimguessing.org"); - //var request = new RestRequest("foo"); - //var response = client.ExecuteTaskAsync(request); - - //Assert.Equal(ResponseStatus.Error, response.Result.ResponseStatus); + Assert.IsType(typeof(WebException), response.ErrorException); + Assert.Equal("Unable to connect to the remote server", response.ErrorException.Message); + Assert.Equal(ResponseStatus.Error, response.ResponseStatus); } /// @@ -73,14 +65,11 @@ public void Handles_Server_Timeout_Error() Assert.NotNull(response.ErrorException); Assert.IsAssignableFrom(typeof(WebException), response.ErrorException); - Assert.Equal("The operation has timed out", response.ErrorException.Message); + Assert.Contains("The operation has timed out", response.ErrorException.Message); } } [Fact] - // The asserts get trapped by a catch block and then added to the response. - // Then the second assert is hit and it just hangs indefinitely. - // Not sure why it can't break out. public void Handles_Server_Timeout_Error_Async() { const string baseUrl = "http://localhost:8888/"; @@ -102,10 +91,31 @@ public void Handles_Server_Timeout_Error_Async() Assert.NotNull(response); Assert.Equal(response.ResponseStatus, ResponseStatus.TimedOut); + Assert.NotNull(response.ErrorException); + Assert.IsAssignableFrom(typeof(WebException), response.ErrorException); + Assert.Equal(response.ErrorException.Message, "The request timed-out."); + } + } + + [Fact] + public void Handles_Server_Timeout_Error_AsyncTask() + { + const string baseUrl = "http://localhost:8888/"; - //Assert.NotNull(response.ErrorException); - //Assert.IsAssignableFrom(typeof(WebException), response.ErrorException); - //Assert.Equal(response.ErrorException.Message, "The operation has timed out"); + using (SimpleServer.Create(baseUrl, TimeoutHandler)) + { + var client = new RestClient(baseUrl); + var request = new RestRequest("404") { Timeout = 500 }; + + var task = client.ExecuteTaskAsync(request); + task.Wait(); + IRestResponse response = task.Result; + Assert.NotNull(response); + Assert.Equal(response.ResponseStatus, ResponseStatus.TimedOut); + + Assert.NotNull(response.ErrorException); + Assert.IsAssignableFrom(typeof(WebException), response.ErrorException); + Assert.Equal(response.ErrorException.Message, "The request timed-out."); } } @@ -128,7 +138,7 @@ public void Handles_Server_Timeout_Error_With_Deserializer() Assert.Null(response.Data); Assert.NotNull(response.ErrorException); Assert.IsAssignableFrom(typeof(WebException), response.ErrorException); - Assert.Equal("The operation has timed out", response.ErrorException.Message); + Assert.Contains("The operation has timed out", response.ErrorException.Message); } } diff --git a/RestSharp/Http.Async.cs b/RestSharp/Http.Async.cs index cfc00e14d..4fff2f2d3 100644 --- a/RestSharp/Http.Async.cs +++ b/RestSharp/Http.Async.cs @@ -368,9 +368,19 @@ private void ResponseCallback(IAsyncResult result, Action callback private static void ExecuteCallback(HttpResponse response, Action callback) { + PopulateErrorForIncompleteResponse(response); callback(response); } + private static void PopulateErrorForIncompleteResponse(HttpResponse response) + { + if (response.ResponseStatus != ResponseStatus.Completed && response.ErrorException == null) + { + response.ErrorException = response.ResponseStatus.ToWebException(); + response.ErrorMessage = response.ErrorException.Message; + } + } + partial void AddAsyncHeaderActions() { #if SILVERLIGHT diff --git a/RestSharp/RestClient.Async.cs b/RestSharp/RestClient.Async.cs index 72419d70c..6fb7db667 100644 --- a/RestSharp/RestClient.Async.cs +++ b/RestSharp/RestClient.Async.cs @@ -275,14 +275,7 @@ public virtual Task> ExecuteTaskAsync(IRestRequest request, { taskCompletionSource.TrySetCanceled(); } - else if (response.ErrorException != null) - { - taskCompletionSource.TrySetException(response.ErrorException); - } - else if (response.ResponseStatus != ResponseStatus.Completed) - { - taskCompletionSource.TrySetException(response.ResponseStatus.ToWebException()); - } + //Don't run TrySetException, since we should set Error properties and swallow exceptions to be consistent with sync methods else { taskCompletionSource.TrySetResult(response); @@ -384,14 +377,7 @@ public virtual Task ExecuteTaskAsync(IRestRequest request, Cancel { taskCompletionSource.TrySetCanceled(); } - else if (response.ErrorException != null) - { - taskCompletionSource.TrySetException(response.ErrorException); - } - else if (response.ResponseStatus != ResponseStatus.Completed) - { - taskCompletionSource.TrySetException(response.ResponseStatus.ToWebException()); - } + //Don't run TrySetException, since we should set Error properties and swallow exceptions to be consistent with sync methods else { taskCompletionSource.TrySetResult(response);