Losing error message with Http Status code 503 in System.net.Http library - c#

We have 2 backend services communicating with each other, both of them are using .net framework with System.net.Http library
One of them returns HTTP status code 503 with some response message("data is not available") when certain condition is met, as shown below in the screenshot
the controller code implementation looks like this:
HttpResponseMessage response = new HttpResponseMessage { StatusCode = HttpStatusCode.ServiceUnavailable, ReasonPhrase = "XXXXXX data is currently not available XXXXXXXXX" };
response.Content = new StringContent("XXXXXX is currently not available XXXXXXXXXX");
return response;
the other service which is calling this API is consuming the response and gets this WebException, which is desired case but the problem is, we lose the message("data is not available") being sent from the first service, when I tried to print the response in the debug window, it showed the following result :
HttpWebResponse aresponse = request.GetResponse() as HttpWebResponse;
'HttpWebResponse aresponse = request.GetResponse() as HttpWebResponse' threw an exception of type 'System.Net.WebException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146233079
HelpLink: null
InnerException: null
Message: "The remote server returned an error: (503) Server Unavailable."
Response: {System.Net.HttpWebResponse}
Source: "System"
StackTrace: null
Status: ProtocolError
TargetSite: null
As shown in the output message is not what I sent from the first service. It's the default message for HTTP status code 503.
Is there a way for me to read the response content from the WebException?

Found the solution, you can read the response from the System.net.WebException
catch(WebException ex)
{
HttpWebResponse errorResponse = webException.Response as HttpWebResponse;
var statusDescription = errorResponse.StatusDescription;
if(statusDescription.Contains("XXXXX"))
{
// Added the condition here
}
}

Related

Getting System.Exception 0:

I have a method that seems to be throwing a "System.Excpetion 0: " without any message. This exception is happening in the production code as seen from the logs but I can't replicate it so far in my local environment. Looks like it comes from RestSharp RestClient(string url) where I've tried an invalid url and a correct url but nothing has replicated such exception yet.
endpoint.url is just a string to hold the base url
endpoint.endpoint is remaining part of the url for the get endpoint i want to hit
endpoint.basicAuth
stack trace says it comes from line 238:
238: var client = new RestClient(endpoint.url);
var request = new RestRequest(endpoint.endpoint, Method.GET);
request.AddHeader("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(": " + endpoint.basicAuthToken)));
var response = client.Execute(request);
if(response.StatusCode != HttpStatusCode.OK)
{
throw new Exception(message: response.StatusCode.ToString());
}
string contentString = response.Content.ToString();
A client.Execute(request) with a invalid url is getting {"The underlying connection was closed: The connection was closed unexpectedly."} therefore the IRestReponse returned has a StatusCode property of 0 and when catching this exception to print out its excpetion message 'throw new Exception(message: response.StatusCode.ToString());' it writes what I'm seeeig of "System.Exception: 0"

"The server committed a protocol violation. Section=ResponseStatusLine" - No request being sent

I'm trying to make a fairly simple POST request to a .NET WebAPI. The request is being made from an Azure Function, in case that makes a difference.
Here's the code:
public async Task SetBackupRecordAsync(BackupRecord backupRecord)
{
var content = new StringContent(JsonConvert.SerializeObject(backupRecord),
Encoding.UTF8,
"application/json");
var uri = new Uri(_httpClient.BaseAddress, "backup");
HttpResponseMessage result = null;
try
{
result = await _httpClient.PostAsync(uri, content).ConfigureAwait(false);
if (result.StatusCode == HttpStatusCode.Accepted)
{
return;
}
throw new Exception($"Unexpected response: The API responded with {(int) result.StatusCode} ({result.StatusCode}) when setting the backup record.");
}
catch (Exception exception)
{
// ...
}
}
And this is the JSON content which is being included:
{"AddedById":14000,"AddedOnUtc":"2019-06-17T09:43:25.9821306Z","Backup":false,"DeletedById":null,"DeletedOnUtc":null,"Id":"4c3ef086-3e2a-4964-bdc1-f5e72f525fbd","LastBackupUtc":null,"Name":"something"}
I've also tried setting every property to a non-null value, which made no difference.
Unlike other questions on the same exception message, this request doesn't even get sent - as soon as _httpClient.PostAsync is called an exception is thrown:
An error occurred while sending the request.
The inner exception says
The server committed a protocol violation. Section=ResponseStatusLine
And the inner stack trace is quite short:
at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
Some additional points:
I can see from Fiddler that no request is being put on the wire so there must be - as the top-level exception says - something about the request itself which is preventing it from being sent.
If I try to hit the same API method from Postman, using exactly the same JSON content, then it works.
I'm able to successfully make GET requests to the same API from the same Azure Function.
So what's wrong with this request?

Error Handling for WebRequest & Response

I am currently running a method that takes a string (a domain name) and checks to see if the site is available or not and passes the information into a Domain object I have created. Currently, I am running into an issue where one of the sites is down and is in turn crashing the application. Below is the method:
private Domain GetStatus(string x)
{
string status = "";
WebRequest req = HttpWebRequest.Create("http://www." + x);
WebResponse res = req.GetResponse();
HttpWebResponse response = (HttpWebResponse)res;
if ((int)response.StatusCode > 226 || response.StatusCode == HttpStatusCode.NotFound)
{
status = "ERROR: " + response.StatusCode.ToString();
}
else
{
status = "LIVE";
}
Domain temp = new Domain(x, status);
return temp;
}
Initial thoughts were that the response.StatusCode == HttpStatusCode.NotFound would handle such an error but it is currently crashing on the line WebResponse res = req.GetResponse(); with the following response:
System.Net.WebException: 'The remote name could not be resolved: 'www.DOMAIN.com''
The issue is due to the fact that your own code is raising an exception.
This can be due to the lack of an internet connection, or a dns resolve issue (which could be caused by the remote party).
So, if the remote server throws an error, you'll get HTTP 500 Internal Server Error, if you can't reach it; your code throws an exception and you'll need to handle that.
To fix this, you can use a try/catch block, something like this:
private Domain GetStatus(string x)
{
string status = "";
try
{
WebRequest req = HttpWebRequest.Create("http://www." + x);
WebResponse res = req.GetResponse();
HttpWebResponse response = (HttpWebResponse)res;
if ((int)response.StatusCode > 226 ||
response.StatusCode == HttpStatusCode.NotFound)
{
status = "ERROR: " + response.StatusCode.ToString();
}
else
{
status = "LIVE";
}
}
catch (Exception e)
{
status = "ERROR: Something bad happend: " + e.ToString();
}
Domain temp = new Domain(x, status);
return temp;
}
By the way, the message,
The remote name could not be resolved
indicates that the host cannot be resolved.
Most likely cause is that your internet is down or, the domain is misspelled or the route to the domain is faulty (e.g. on intranet environments).
HttpWebRequest is all about HTTP protocol, which is kind of a agreed upon language.
But if the person on the other end doesn't exists, so how should you expect him to return you an "Hello" for example ?
So StatusCode is really just about if the actual remote site did response, what did the response state was according to the request resource, is it Successful(200) ? Not Found(404) ? Unauthorized(401) and so on.
Exception means, i couldn't reach the site because of many reasons.
StatusCode means the resource you requested has return this response type.
But a more actual check if the site is alive or not, is querying a static page and not getting exception, a more healthy check, will querying a static page, you will always count as being Healthy; meaning will return a 200 OK response.
So it all depends on what LIVE means for you (or the client using it).
Is it the remote host is actually receiving requests, meaning no Exceptions.
Or it actually means, he's able to get requests and returning me a valid StatusCode response that i expect him to return (Healthy).

HttpWebRequest.GetResponse methods throws 404 exception

I want to download one image from url using console application.
I have used following code:
string sourceUrl = "http://i.ytimg.com/vi/pvBnYBsUi9A/default.jpg"; // Not Found
//string sourceUrl = "http://i.ytimg.com/vi/OrxZAN1FZUY/default.jpg"; // Found
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sourceUrl);
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (Exception)
{
}
Above code throws exception in line "response = (HttpWebResponse)request.GetResponse();"
but when I am accessing "http://i.ytimg.com/vi/pvBnYBsUi9A/default.jpg" url in my browser then image will be display.
What I am missing here?
I tried that url "http://i.ytimg.com/vi/pvBnYBsUi9A/default.jpg" in Chrome
developer tools. It also receives a 404, but the response includes the image, which displays.
Your code is not the cause of the exception. The site is returning a 404 and your code gets an exception.
You could write logic to look at the response even if you get a 404 and decide whether to take it anyway, as the browser does.
It looks like you can get the response returned by the site if you catch WebException, which allows you to see the http request status and the response, per the documentation.
Example from the .Net 4.5 doc...
try
{
// Creates an HttpWebRequest for the specified URL.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
// Sends the HttpWebRequest and waits for a response.
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
if (myHttpWebResponse.StatusCode == HttpStatusCode.OK)
Console.WriteLine("\r\nResponse Status Code is OK and StatusDescription is: {0}",
myHttpWebResponse.StatusDescription);
// Releases the resources of the response.
myHttpWebResponse.Close();
}
catch(WebException e)
{
Console.WriteLine("\r\nWebException Raised. The following error occured : {0}",e.Status);
}
catch(Exception e)
{
Console.WriteLine("\nThe following Exception was raised : {0}",e.Message);
WebException has Response and Status properties. So it looks like the .Net way to deal with this is to catch WebException and determine how to handle based on the status and response content (if necessary).

How do I get headers from a 401 Server Error

I'm writing a port scanner to detect web services running on the local network. Some of these web services require basic authentication - I don't know the username/ password for these services, I just want to list them, so I can't provide the credentials at this stage. I'm using the code:
var request = (HttpWebRequest)WebRequest.Create("http://" + req);
request.Referer = "";
request.Timeout = 3000;
request.UserAgent = "Mozilla/5.0";
request.AllowAutoRedirect = false;
request.Method = WebRequestMethods.Http.Head;
HttpWebResponse response = null;
try
{
response = (HttpWebResponse) request.GetResponse();
// I want to parse the headers here for the server name but as the exception is thrown the response object is null.
}
catch (Exception ex)
{
//401 error is caught here - response is null
}
I'm then parsing out the server name from the headers that are returned - I know they are being returned because I can see them with fiddler but the HttpWebResponse object is set to null as the GetResponse() method is throwing an exception. Basically - how do I get it to not throw and exception but return the headers along with a status code of 401.
If you catch a WebException you'll have access to ex.Response and you can retrieve your headers from there.

Categories

Resources