I'm creating a simple (console) application to remote control a video device (encoder) using HTTP requests with C#. I need to send XML data to the device, and the device responds by sending XML data.
The code I'm using to do this request is the following: http://pastebin.com/59CXR3m9
When I try to test this code, the request is created and the stream is written. I can see the "stream created" flag as expected, but then, nothing happens. Application seems to be stuck, even when I'm using a specific low timeout (5 secs for example).
To troubleshoot this, I activated System.Net trace logging. I found a WebException is thrown by GetRequestStream, but for one reason, this exception is not caught by the try/catch in my code. Here's the exception:
System.Net Error: 0 : [1344] Exception in the HttpWebRequest#44223604:: - The underlying connection was closed: The connection was closed unexpectedly.
I can send the complete trace on demand.
I also did another trace with the callstack, showing the exception is thrown by GetRequestStream: http://pastebin.com/vE5QZGBe
I tested this code with another device and it worked fine, so this is something also device-related, but I can't see any reason why that exception would not be caught. And as this can be a production situation, the code has to be able to handle this correctly (and not wait endlessly for a response).
Did somebody already have this type of behavior? Any suggestions are greatly appreciated :)
Thanks!
FYI: I also have a trace of a successful request, if it can help
Related
I have a .Net application up and running.
We have had a fluctuating connection yesterday. While testing in such scenarios we had received multiple server time out exception emails like below.
Server Time Out
Type : System.Web.HttpException, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Message : Request timed out.
Source :
Help link :
WebEventCode : 3001
ErrorCode : -2147467259
Data : System.Collections.ListDictionaryInternal
TargetSite :
HResult : -2147467259
Stack Trace : The stack trace is unavailable.
Additional Info:
IMPORTANT: Above exception occurred while doing a ajax post by a button placed with in update panel.
My question here is why would a slow internet on client side raise such server time out exception?
Isn't server timeout exception is related to such cases where server cannot execute the request in underlying time mention in HttpRuntime setting? May be due to some lengthy operation or some long database execution which takes longer than the time mentioned in setting under HttpRuntime.
If server is not able to connect to the client due to clients fluctuating internet, then Client Disconnected exception would be raised which we did yesterday. But I am not able to conclude the reason for this server timeout exception.
I already know that increasing the execution timeout will fix the issue, but I have to provide technical explanation for the reason as to why such exception of Server Timeout raised.
My best guess here is that the ajax request would be doing some continuous communication with server for executing of single request server and would raise timeout exception if it does not receives some required further communication messages due to client's bad internet. I have search over internet for the same to support my guess but in vain.
Also to provide environmental details, there is a load balancer serving the request.
Any help would be highly appreciated.
It is because (as you write) the connection of client to server is slow, so if the server (or client) sending data to this server, connection can´t handle it, so you get timeout error, because the data can´t been transfered in defined time.
You also write, that this is caused by sending Ajax request, so maybe try to increase execusion timeout in web configuration file (web.config):
<httpRuntime executionTimeout = "number(in seconds)"/>
More about executionTimeout here and here about Ajax requests.
Firstly, I think the cause of this error is because of execution time required by your application request connecting with the remote server is exceeding the currently set ASP.NET request execution timeout value. As per the MSDN Exception Document, default value is set to 110 seconds, in that it is remarked like:
The ExecutionTimeout property indicates the maximum number of seconds
a request is allowed to execute before being automatically shut down
by ASP.NET.
So based on error detail with event code 3001 occurs because no response was received during the time-out period for a request. You can use IIS troubleshooting failed request mechanism to figure it out exact issue like any poor performance/deadlocks when making calls from your ASP.NET application.
Secondly, it is not related to user's internet connectivity issue otherwise you get exception with status like connection-closed or keep alive failure. See this article for detail. The browser is going to wait for a 60 minutes(which is very long period of time that server isn't going to answer any request)for server to response.
And at any case when the browser abandons any request, it is going to close the socket and you'll get an error page from the browser. You don't get anything related to sever-end.
Okay I tried to play a little bit with the StatsManager but I always got an exception trying to use anything with it when comes to
Set a stat
Get a stat
Because I doubted myself I had the idea just to use the UWPIntegration sample that is on Github . I also added the Leaderboard items to my own project so the code works with my test sandbox. Logging in works as it should just StatsManager causes the issues.
But as with my own code I just get the same error / exception which is the following. I assume there is a bug in the code provided or the service configuration is not working as intended.
System.AggregateException occurred HResult=0x80131500 Message=One or more errors occurred. Source= StackTrace: at
System.Threading.Tasks.Task1.GetResultCore(Boolean
waitCompletionNotification) at
Microsoft.Xbox.Services.XboxLiveHttpRequest.<>c__DisplayClass35_0.<GetResponseWithAuth>b__1(Task1
getResponseTask) in
D:\Data\VisualStudio\Projects\xbox-live-api-csharp\Source\api\XboxLiveHttpRequest.cs:line
117 at System.Threading.Tasks.Task.Execute()
Inner Exception 1: AggregateException: One or more errors occurred.
Inner Exception 2: WebException: The remote server returned an error:
(404) Not Found.
Issue was found. My service.config used a wrong parameter name, see below in the comments of the solution.
There are a few different reasons why this might be the case. Not surprisingly, it means the cloud can't find the stat you've requested.
If you use Fiddler, you can capture the call and share with me the correlationID header. If you don't know Fiddler, let me know and I can help you.
However, some ideas off the top of my head
Make sure that you're in development mode - your sandbox is the one from the dev center site. If you aren't sure, you can use the Windows Device Portal to see what your sandbox is - just click on Xbox Live in the left hand navigation.
Make sure you have hit "Test" on the dev center page where you defined your featured stats and leaderboards.
Make sure you are requesting the stat by the ID name you specified in the config window, not the display name.
Essentially, while using the .NET version of the Email Migration v2 Google API our application is sending up too many requests per second to a single Google Apps mailbox/user; greater than 1 Request per second. A GoogleApiException is being returned which is fine, and expected, however the body of the error message states a service unavailable (503) error has occurred, but yet the "HttpStatusCode" property of that same GoogleApiException instance is equal to an Http status code of Gone (410), I will include a code snippet and some log output below. At this point, see the questions section at the bottom or read on for better detail.
What steps will reproduce the problem?
Create a process/application that does the following:
Create a Google.Apis.Admin.email_migration_v2.AdminService object, properly initialize it using your OAuth2.0 credentials.
For each message that needs to be sent to Google Apps Create a Google.Apis.Admin.email_migration_v2.MailResource.InsertMediaUpload instance using the AdminService object from above through using AdminService.Mail.Insert() providing proper parameters.
Call MailResource.InsertMediaUpload.UploadAsync while catching any errors that occur.
Do the following:
Begin sending messages at an exponential rate by spooling off hundreds of instances of this process/application all pointing to the same user, using the same OAuth2.0 credentials.
Sit back sip your mountain dew and wait for the [503] errors to roll in...
Once errors start rolling in close down your applications.. no need to hammer the poor Google servers other than for testing the applications exception handling..
What is the expected output? What do you see instead?
Using an instance of the following type: Google.GoogleApiException
One would expect to see the instance's HttpStatusCode property be equivalent to System.Net.HttpStatusCode.ServiceUnavailable instead of System.Net.HttpStatusCode.Gone
What version of the product are you using?
Google.Apis.Admin.Email_Migration_v2 (1.8.1.20)
What is your operating system?
Windows Server 2008 R2 Enterprise (SP1)
What is your IDE?
Visual Studio 2013 Premium
What is the .NET framework version?
4.0.30319
Please provide any additional information below.
Here is a code snippet of the method being called for uploading purposes:
UploadStatus TryUpload(MailResource.InsertMediaUpload insertMediaUpload)
{
try
{
IUploadProgress uploadProgress = insertMediaUpload.UploadAsync(_cancellationToken).Result; // Task.Result locks this thread until completed.
if (uploadProgress != null && uploadProgress.Exception != null)
{
// Display additional information on any of the various exceptions that can be returned by the upload call.
HandleUploadProgressException(uploadProgress);
}
return uploadProgress != null ? uploadProgress.Status : UploadStatus.Failed;
Here is a code snippet from the method that is displaying the output of the exception.
void HandleUploadProgressException(IUploadProgress uploadProgress)
{
if (uploadProgress.Exception is GoogleApiException)
{
GoogleApiException gApiEx = uploadProgress.Exception as GoogleApiException;
throw new vsEventException(vsMapEvent.MapHttpError(gApiEx.HttpStatusCode, vsEventMessages.Id.errGmailUnidentifiableGoogleApiException),
String.Format("GoogleApiException handled in GmailMessenger.HandleUploadProgressException. HttpStatusCode: {0}", gApiEx.HttpStatusCode),
gApiEx);
}
Here is paraphrased output of the GoogleApiException handled by the HandleUploadProgressException method: (note using a custom logging class;
outputting to DebugView)
** Context Info **
Error attempting to write item to Gmail...
** Event Details **
VS-EventID: 30003(errGmailTryUpload) GoogleApiException handled in
GmailMessenger.HandleUploadProgressException. HttpStatusCode: Gone
** Inner Exception Details **
The service admin has thrown an exception: Google.GoogleApiException:
Google.Apis.Requests.RequestError
Service unavailable. Please try again [503]
Errors [ Message[Service unavailable. Please try again] Location[ - ]
Reason[backendError] Domain[global] ]
at
Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task)
at
Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task
task)
at
Google.Apis.Upload.ResumableUpload`1.d__e.MoveNext()
Questions:
Can anyone shed some light on if this is expected behavior or a bug?
If this is the expected result how should the application handle a 410 based error? I know that when most if not all 400 errors are encountered processing of that particalar item should stop, but this does not seem to be a local issue, more a server side issue.
I appreciate any responses returned, I know it can be hard for questions as specific as this.
What's wrong with this? I get the exception
An unhandled exception of type 'System.Net.WebException' occurred in System.dll
Additional information: An exception occurred during a WebClient request."
Here's the part of the code with the WebClient.
I need to learn how to use the code part properly one day....
http://pastebin.com/1Z90bvqB
Any answers are greatly appreciated.
(I'm not sure I agree with the ethics of the code itself, but ignoring that...) a WebException is caused by a line that connects to the internet, so either one of the lines like:
webClient.DownloadFile(String.Copy(WeepCraft), #"%appdata%\.minecraft\versions");
Or the line:
Process.Start("http://www.wirez.cf/");
In the latter case, unless I'm misunderstanding, is this actually a process you can start??
Anyway, around all the lines, you'll need to have a try/catch for WebException in case it can't connect for whatever reason (eg Internet down, wrong URL used, server returns HTTP Error code etc etc), and decide how to handle it.
It's a pretty common Exception whenever something tries to do a http request and the server can't be connected to for whatever reason.
Here is the complete error message:
An exception of type
'System.Web.HttpException' occurred in
System.Web.dll but was not handled in
user code
Additional information: The remote
host closed the connection. The error
code is 0x80070057.
and the offending code:
char[] buffer = oPage.HTML.HTML.ToCharArray();
Page.Response.Write(buffer, 0, buffer.Length);
Page.Response.Flush();
Page.Response.End();
The oPage.HTML.HTML is a string in a custom page object used by our app. The exception triggers on Page.Flush() and appears to be benign -- I just hit "continue" and everything goes along fine. This never appears at run time.
I have chased many, many Google hits down many rabbit holes and have found nothing. Visual Studio 2005, Vista Ultimate (IIS7).
I've been dealing with this same error for a while now, and my understanding is that when Flush is called, there must be a connection on the other end, otherwise, this error is thrown. It's easy to get into a "fire-and-forget" kind of model when writing web pages, but when the client disconnects (in this debugging case, you're the client), there's nowhere to flush to.
There are two solutions I've found to this:
Wrap Response.Flush and catch the exception.
Check Response.IsClientConnected before you call flush.
I'm not 100% sure about the second one...I'm still in the process of checking that one out.
Good luck!