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

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

Related

Any C# library to do webrequest similar to httpwebrequest but not throwing exceptions

I 'm looking for a similar library or class like httpwebrequest which does not throw exceptions on http codes. (c# language)
Problem with httpwebrequest is that it behaves the http error codes (like 401,403 and ...) as exceptions and throws an exception in case of these. You may know that exception throwing and handling is expensive. for example a successful request takes about 30 ms on my system,but another request which causes exception takes about 250!
I 'm making lots of request that causes this http error codes and it affects my code performance alot.
I have tried webclient,webrequest,httpclient and all are the same in this.
Any opinion on a alternative library or how to avoid these exceptions ?
HttpClient.GetAsync() won't throw an exception on a 400-level error. Though it will throw an exception for "an underlying issue such as network connectivity, DNS failure, server certificate validation or timeout."
Also, the HttpReponseMessage it produces has a handy IsSuccessStatusCode property.
Check out RestSharp. It's a great tool for creating web requests

Google.Apis.Admin.Email_Migration_v2 HTTP 410 status code returned for a 503 error

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.

HttpRequestException vs WebException

This is a general question that I'm confused about. I thought once a REST request was made, an error would come back via a WebException. In one case I have I'm getting a HttpRequestException, which doesn't allow me to get the HTTP status code.
I'm new to this stuff, but what is the difference between these? Why are there two types? When does one get used as opposed to another?
WebException seems to work well. HttpRequestException seems like a very weak version of it, where it knows the status code (in it's message) but it won't tell me explicitly what it was.
EDIT:
I'm using a HttpClient. Specifically calling client.GetStreamAsync().
There are three distinct failure scenarios:
a) You could not connect to the server or proxy, in which case a HttpRequestException is thrown. Be aware if your server is down and you are running fiddler, you will never see this exception, you will get a 5XX status code.
b) When reading/writing a network stream, there is some kind of interruption you will get an IOException.
c) You will get back a response with a HttpStatusCode with a 4XX/5XX status code. If your client application chooses to call response.EnsureSuccessStatusCode() then a HttpRequestException will be thrown.
If you decide to call EnsureSuccessStatusCode you are making an explicit decision that you don't care about status codes other than the fact that it was success/fail.
If you really need to bubble up an exception and then later handle the status code then I suggest you create your own extension method to replace EnsureSuccessStatusCode and create your own exception that can store the status code. Or preferably, translate the status code into one of a few different exceptions based on the corrective action you wish to take.
WebException Class: The exception that is thrown when an error occurs while accessing the network through a pluggable protocol.
HttpRequestException Class: A base class for exceptions thrown by the HttpClient and HttpMessageHandler classes.
I think the inner exception of a HttpRequestException could be a WebException however I'm not sure it ever is.
Note, a 404, 302 or whatever response other than a 200 (OK) is not an exception. Those responses are perfectly valid HTTP responses.
https://github.com/dotnet/runtime/pull/32455 adds StatusCode to HttpRequestException in .NET 5.

CommunicationException with 'not recognized sequence' message in WCF

I get a CommunicationException while using WCF service. The message is:
The remote endpoint no longer recognizes this sequence. This is most likely due to an abort on the remote endpoint. The value of wsrm:Identifier is not a known Sequence identifier. The reliable session was faulted.
The exception is thrown in a moment after a contract method was called. Before calling contract method the channel state is Opened. I restore my service client after catching this exception and for some time it works fine. But then this error occures again. It seems like some timeout is exceeded, but I can't understand which one exactly.
I use wsHttpBinding with reliableSession enabled. The InactivityTimeout is set to half an hour and I'm sure it's not exceeded, because exception is thrown earlier.
I solved the problem. The reason was RecieveTimeout on a server side. It was set to 1 minute, so after having no requests during 1 minute server used to close a channel, and when client tried to call a contract, channel was already crashed due to the timeout.
I found the solution after reading this article:
http://msdn.microsoft.com/en-us/library/system.servicemodel.reliablesession.inactivitytimeout.aspx
I received this error while setting up a new WCF service which returned a list of objects.
My understanding is that WCF services can only pass very simple objects back n forth.
So objects with anything other than public properties will not be transferable.
The object had a read only property doing a bit of logic.
Once I got rid of this, rebuilt, and updated the web references, the error went away.
Tip:
If you're returning a object and it has properties check the gets and sets of each one.
We had a problem around it.
I have seen this happen when an application pool gets recycled.
Look at the very last section of this blog about service recycling .

What causes the System.Web.HttpException with error code 0x80070057 on Page.Flush while debugging in VS2005?

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!

Categories

Resources