HttpClient SendASync crashes - c#

I have a service that after my latest updates have started crashing.
It does crash on both the server and in my development environment, so it's not system specific.
It crashes on code generated by Autorest
_httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken)
.ConfigureAwait(false);
It throws a StackOverFLowException and nothing is attached... There is no more info given.
Fiddler shows that no data is being sent, so it dosen't start sending anything.
As far as i can recall, the only change i did when it stopped working is i changed another autorest namespace out.

Actually managed to solve it myself.
I was trying to add an Accept-Header by using a delegate, this somehow created an infinite loop thus causing a StackOverflow.
The correct way of adding it is:
Client.HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
But i was adding it like this
httpRequest.Headers.Add("Accept", "application/json");
Easy mistake and very weird error message... ^^

Related

debug .net library using HttpClient? (Get request hangs/time out)

Update/Edit
I pull their repo build it and step through it, I find the HttpClient is simply timing out here
var result = Await client.SendAsync(request) //Times out after a while
If i change it to a blocking call, it works
var result = Await client.SendAsync(request).GetAwaiter().GetResult() //Works
The next call, gets the results Async, and it works as expected
var body = await result.Content.ReadAsStringAsync(); //Works if the Send is synchronous
Why would sending the request Async timeout, yet performing the send blocking and then reading the result async work? I don't quite understand what is happening here?
Original Post
I'm struggling to debug an issue i'm facing using a 3rd party library that handles the HTTP requests to their API. I'm targeting .Net 4.6.1 - It's a mess of a web project with both WebApi and webforms.
The package is using HttpClient() for it's requests (Postmark.Net)
PostMark Package URL
https://github.com/wildbit/postmark-dotnet/tree/71c05efafd266a4403f8e6c18a8b485252082fd3
Issue
When I run the project, the application just appears to hang. It does not timeout and return back to the caller, it just appears stuck. In my debug window it just shows the threads exiting with code 0.
Sample Code
Dim cc = New PostmarkDotNet.PostmarkClient("key")
Dim msg = cc.GetOutboundMessageDetailsAsync("some-id").GetAwaiter.GetResult()
Log.Debug(msg.Status.ToString & " - " & msg.ReceivedAt.ToString() & " - " & msg.To.FirstOrDefault.Email.ToString())
Note: Intentionally using getAwaiter to block the thread to help troubleshoot.
What I've Tried:
Created a new .net project targeting the same framework version (4.7.1) - The library and code functions as expected; so it must be related to this project
Clean / Rebuild the project
Running Fiddler to see what is happening on the wire - i see an outbound request with a response with the SSL cert from the API - then nothing. I'm thinking perhaps some issue is occurring around the SSL handshake - however, i doubt it is a TLS issue since a test project on same machine worked as expected.
Further Questions:
How can I debug or step into the library itself to see what is happening there?
The package requires .Net.Http 4.3.4, but in my web.config i'm showing a bindingRedirect to 4.2.0.0, but in my test project i threw together seeing the same thing and not having an issue.
Suggestions?

Hard crash of .NET Core 3.1 app using RestSharp ExecuteAsync

I've been experiencing this for a while with RestSharp, and worked around it by using TaskCompletionSource.
I recently upgraded to the latest version of RestSharp (106.11.4), and still seeing it, so I wanted to ask if anyone knows a potential cause.
Right now I have to define USE_TASK_COMPLETION_SOURCE, or my console app will hard shutdown on the ExecuteAsync call.
I tried throwing a ConfigureAwait(false) in there, as a guess, but that didn't change anything.
Seems like a pretty normal use case; anyone ever seen this before (and solved it)?
Crashes:
return await client.ExecuteAsync(request, cancellationToken);
Works:
var tcs = new TaskCompletionSource<IRestResponse>();
client.ExecuteAsync(request, r =>
{
tcs.SetResult(r);
});
if (!tcs.Task.Wait(DEFAULT_REST_TIMEOUT))
throw new InvalidOperationException($"REST request timed out after [{DEFAULT_REST_TIMEOUT}].");
return tcs.Task.Result;

RestSharp Response error: "Only one usage of each socket address (protocol/network address/port) is normally permitted"

I'm using RestSharp to communicate with a .Net Core Web API. Both Client and Server are written by me.
I have a suite of Services all inheriting a Base class which contains an async method to perform the request via a RestClient. Here is the method within the base class that creates the RestClient.
private async Task<ServiceResponse> RequestAsync(ServiceRequest request)
{
try
{
var result = await new RestClient(_digiCore.Config.GetApiBaseUrl()).ExecuteTaskAsync(request.Request, request.CancellationTokenSource.Token);
switch (result.StatusCode)
{
case HttpStatusCode.OK:
case HttpStatusCode.Created:
case HttpStatusCode.NoContent:
return new ServiceResponse
{
Code = ServiceResponseCode.Success,
Content = result.Content
};
// User wasn't authenticated for this one - better luck next time!
case HttpStatusCode.Unauthorized:
Logger.LogError($"Unauthorized {request.Method.ToString()}/{request.Path}");
default:
Logger.LogError($"An error occurred {request.Method.ToString()}/{request.Path}");
}
}
catch (Exception e)
{
Logger.LogError($"A Rest Client error occurred {request.Method.ToString()}/{request.Path}");
}
}
My understanding is that the RestClient (unlike HttpClient) is thread safe and OK to create a new instance each time.
When Load testing my application, one I reach a certain point, I find that I occasionally receive the following response back from the API. Refreshing the page might bring back the correct result, or I might get another error. When the Load Test has finished everything goes back to normal. The numbers of the load test are nothing crazy, so its started to get me worried about real-life performance...
Only one usage of each socket address (protocol/network address/port) is normally permitted
I believe this is down to port exhaustion. Both API and Client are running in Azure as App services.
I have tried making the RestClient part of a singleton service, and checked that it is only created once - but this did not alleviate the issue.
I have also looked into setting the DefaultConnectionLimit in the Startup function of my startup class from the default (2) to 12, but I did not see any improvements here either.
I'm really struggling to see how I can improve this...
Found out the reason for this...
It seems there is currently an issue with RestSharp whereby socket connections are not closed down immediately and instead are left in TIME_WAIT state.
This issue is currently logged with the RestSharp guys here ->
https://github.com/restsharp/RestSharp/issues/1322
I have chosen to switch over to using HttpClient - and running the exact same load test I had zero problems.
Here is an screenshot taken from Azure showing the difference between the two load tests.
Was with my app using RestSharp
Was with my app using Http Client
Hope this helps somebody. It's a shame I had to ditch RestSharp as it was a nice little library - unfortunately with an issue like this it's just too risky to run in a Production environment.

Using RestSharp with Xamarin - Execute() throws exceptions when HTTP request fails

I'm using the RestSharp 105.2.3.0 in my project which runs on Xamarin.Android 6.0.1.10.
Everything was ok, but couple of days the call to Execute() method started throwing exceptions if HTTP requests did not succeed (I guess it's related to the update of the Xamarin platform?).
For example, I receive "System.Net.WebException: The remote server returned an error: (403) Forbidden." for the 403 response status code and "System.Net.Sockets.SocketException: No route to host" if the host is unreachable.
This is weird, since on this page - https://github.com/restsharp/RestSharp/wiki/Recommended-Usage - I see:
Note that exceptions from Execute are not thrown but are available in the ErrorException property.
Also, I found a SO question which is more or less for the same issue.
The proposed solution is to set the IgnoreResponseStatusCode property:
var client = new RestClient();
client.IgnoreResponseStatusCode = true;
But I don't see this property among those available in RestClient.
How could I fix this? Of course, I can wrap the Execute call in try..catch, but I would prefer to avoid it since the Execute is not supposed to throw exceptions in the first place.
I've figured it out.
The problem was related to the fact that in the Exception settings window (Debug -> Exceptions...) in Visual Studio all checkboxes were checked in the "Break when an exception is: Thrown" column.
So the exception was caught by the RestSharp code, but VS was still breaking the execution at the Execute call as it was configured to do so.
Screenshot: http://i.stack.imgur.com/a0Fc4.png

Adjust HttpRequst Timeout Before Creating any HttpWebRequest

In C# 5 and winform, I used a library created by Telegram Company. In this library there is a function SendDocument(UserId,DocumentStream). I know in this function, they used some HttpWebRequest, and the Timeout property of that is not handled. because sometimes it can't send large documents and after exact 100 seconds(default timeout in DotNet), the function throws an exception The task was canceled.
From the document of Telegram Company, we can send 50 MB files and my example files is about 15 MB.
Ok, Now I want to adjust the timeout of all HttpWebRequest of my server but I don't have any feature for this.
Can I adjust all HttpWebRequest.Timeout property in my server??
This is not directly related to your question, but may help ease your mind.
My advice is, don't bother adjusting the timeout. It is not likely to help. Here is what I have gone through:
I have tried to upload a 20M mp4 video file using Telegram Bot API. From a Raspberry Pi, it took 5 minutes, then returned a 504 Gateway-Timeout error. From a hosted server, it took 1 minute, then returned a 504 Gateway-Timeout error. In both cases, however, the video did eventually reach the recipient 5 minutes later. So, the upload seemed somewhat successful, yet not quite successful.
I tried to fix the problem by streaming the upload. Same problem persisted.
I tried to adjust the HTTP timeout parameter. Same problem persisted.
I tried to use cURL to make the request (instead of using telepot, a Python library I author). Same problem persisted.
I suspect the problem lies with the Telegram servers, so I talked to Bot Support. They got back to me once, saying they have made some improvements and asked if I still have the same problem. But same problem still persists.
So, it seems the problem does lie with the Telegram servers. It's not your code.
I know it's a pretty old question but may be my answer will help somebody. When I tried to send cosiderably large files via my bot I received Telegram.Bot.Exceptions.ApiRequestException: Request timed out and the only solution I found was this issue. Which wasn't really helpfull because if you check source code then you'll see that passing cancellation token does nothing with request timeout. But then I saw that you can pass HttpClient to your bot client instance and make it something like this:
_httpClient = new HttpClient();
_httpClient.Timeout = new TimeSpan(0, 5, 0); // 5 min
_client = new TelegramBotClient(botConfig.Token, _httpClient);
Hope this will help

Categories

Resources