I'm getting a System.Net.WebException saying:
The remote server returned an error: (403) Forbidden.
This is what I'm expecting since invalid headers are being passed in with the http request. However, my code does not seem to be catching the exception like I would expect.
Here is the code:
private void callback(IAsyncResult result)
{
Debug.WriteLine("Callback");
HttpWebResponse response = null;
try
{
response = (result.AsyncState as HttpWebRequest).EndGetResponse(result)
as HttpWebResponse;
}
catch (WebException e)
{
Debug.WriteLine("Exception: " + e);
}
catch (Exception e)
{
Debug.WriteLine("Unknown exception: " + e);
}
}
Why is the exception not caught?
Take a look here.
Probably you should do something like this:
Task<WebResponse> task = Task.Factory.FromAsync(
request.BeginGetResponse,
asyncResult => { callback(asyncResult); },
(object)null);
return task.ContinueWith(t =>
{
if (t.IsFaulted)
{
//handle error
Exception firstException = t.Exception.InnerExceptions.First();
}
else
{
return FinishWebRequest(t.Result);
}
});
Related
I don't understand why but I'm receiving Flurl Exceptions and those are not being caught by the try/catch block. Any ideas on why that's happening?
Here's the code:
try
{
var x = await Utils.Sales.GetUrl()
.PostJsonAsync(new Sale
{
MerchantId = Constants.Sandbox.MerchantId
})
.ReceiveJson<Sale>();
var b = x;
}
catch (FlurlHttpTimeoutException)
{
//LogError("Timed out!"); //todo:
}
catch (FlurlHttpException ex)
{
var x = ex.Message;
//todo:
//if (ex.Call.Response != null)
// LogError("Failed with response code " + call.Response.StatusCode);
//else
// LogError("Totally failed before getting a response! " + ex.Message);
}
catch (Exception ex)
{
var a = ex.Message;
}
Here's the output (the only reason why I know the exception is being thrown):
Maybe this page will help https://msdn.microsoft.com/zh-cn/library/jj619227.aspx
Sorry don't have a english version, you can try google translate it.
It's someting wrong with you catch exception type or await code.
Try this way catch your exception:
```
try
{
await t1;
}
catch (AggregateException ex)
{
var innerEx = ex.InnerExceptions[0];
if (innerEx is NotSupportedException)
{
...
}
else if (innerEx is NotImplementedException)
{
...
}
else
{
...
}
}
```
I've developed a simple Web Service and a Windows Phone 8 app to consume it.
Everything works as intended but the way my current (working) code stands, it's assuming the Web Service to always be running and available. Seeing as that may not always be the case, I'd like to try and add some kind of connectivity testing before I start sending requests. I've read that there's no straightforward way of being certain that the WS is up and running other than querying it somehow.
With that in mind, here's what my LoadData method structure looks like (Feb. 26th):
public void LoadData(string articleCode = null)
{
try
{
this.ArticleItems.Clear();
MyServiceSoapClient ws = new MyServiceSoapClient();
CheckWebService();
if (this.isWebServiceUp)
{
if (!String.IsNullOrEmpty(articleCode))
{
ws.GetBasicDataAsync(articleCode);
ws.GetBasicDataCompleted += Ws_GetBasicDataCompleted;
//(irrelevant code supressed for clarity)
this.IsDataLoaded = true;
}
}
else
{
this.ArticleItems.Add(new ItemViewModel() { LineOne = "Could not connect to Web Service." });
ws.Abort();
}
}
}
And it still throws an unhandled CommunicationException error.
EDIT: After taking into consideration both suggestions and doing some searching, I've tried to set up a "heartbeat"-type method but it's not working correctly. Asynchronous programming is a relatively new paradigm for me so I most likely am missing something but here goes my attempt at an implementation thus far (getting a "Unable to cast object of type 'System.Net.Browser.OHWRAsyncResult' to type 'System.Net.HttpWebResponse'" exception):
public void CheckWebService()
{
try
{
Uri wsURL = new Uri("http://localhost:60621/WebService1.asmx");
//try accessing the web service directly via its URL
var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(wsURL);
request.Method = "HEAD";
//next line throws: "Unable to cast object of type 'System.Net.Browser.OHWRAsyncResult' to type 'System.Net.HttpWebResponse'."
using (var response = (System.Net.HttpWebResponse)request.BeginGetResponse(new AsyncCallback(ServiceCallback), request))
{
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
throw new Exception("Error locating web service");
}
}
}
catch (System.ServiceModel.FaultException fe)
{
this.ArticleItems.Add(new ItemViewModel() { LineOne = fe.Message });
}
catch (System.ServiceModel.CommunicationException ce)
{
this.ArticleItems.Add(new ItemViewModel() { LineOne = ce.Message });
}
catch (System.Net.WebException we)
{
this.ArticleItems.Add(new ItemViewModel() { LineOne = we.Message });
}
catch (Exception ex)
{
this.ArticleItems.Add(new ItemViewModel() { LineOne = ex.Message });
}
}
private void ServiceCallback(IAsyncResult asyncResult)
{
try
{
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)asyncResult.AsyncState;
using (var response = (System.Net.HttpWebResponse)request.EndGetResponse(asyncResult))
{
if (response != null && response.StatusCode == System.Net.HttpStatusCode.OK)
{
this.isWebServiceUp = true;
request.Abort();
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
I have the following code (the important bits):
while(true){
BrokeredMessage message = subscriptionClient.Receive();
if (message.Properties.ContainsKey("MessageType"))
{
try
{
SmsService.Instance.SendSms("lenio", user.PhoneNumber, SomeString);
}
catch (Exception ex)
{
throw;
}
}
}
The code runs continuously and the message I receive is handled and SomeString is just some string.
The SmsService class looks like this:
public class SmsService
{
private const string Username = "******";
private const string Password = "******";
private static SmsService _instance = null;
private static readonly Lazy<SmsService> lazy =
new Lazy<SmsService>(() => new SmsService());
private SmsService() { }
public static SmsService Instance
{
get
{
return lazy.Value;
}
}
public bool SendSms(string from, string receiver, string message)
{
string url = UrlBuilder(from, receiver, message);
HttpWebRequest newRequest = (HttpWebRequest)WebRequest.Create(url);
HttpStatusCode statusCode = new HttpStatusCode();
try
{
HttpWebResponse response = (HttpWebResponse)newRequest.GetResponse();
statusCode = response.StatusCode;
}
catch (WebException we)
{
statusCode = ((HttpWebResponse)we.Response).StatusCode;
}
if (statusCode == HttpStatusCode.OK)
{
Logger.Instance.AddToLog(0, "SMS", "Sms Send to: +" + receiver);
return true;
}
else
{
Logger.Instance.AddToLog(0, "SMS", "Failed to send sms to: +" + receiver);
return false;
}
}
public string NewLine()
{
return "%0a";
}
private static string UrlBuilder(string from, string to, string message)
{
string newTo = "45" + to;
string encodedMessage = message.Replace(" ", "+");
string encodedfrom = from.Replace(" ", "+");
return "http://sms.sms1290.dk/?username=" + Username + "&password=" + Password + "&to=" + newTo + "&from=" + encodedfrom + "&message=" + encodedMessage;
}
}
I have a problem that sometimes, if I receive a lot of messages I get a "Object reference not set to an instance of an object." exception on SmsService. I sometimes also get an "operation timed out" on:
HttpWebResponse response = (HttpWebResponse)newRequest.GetResponse();
I have made a gist with more code if needed: https://gist.github.com/Niclassg/54b908fbf5cc9b3e11a7
Stacktrace on "operation timed out":
> lenioServiceBus.exe!lenioServiceBus.SmsService.SendSms(string from, string receiver, string message) Line 44 C#
lenioServiceBus.exe!lenioServiceBus.Program.AlarmDeactivated(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 489 C#
lenioServiceBus.exe!lenioServiceBus.Program.msgHandler(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 109 C#
lenioServiceBus.exe!lenioServiceBus.Program.Main(string[] args) Line 59 C#
[External Code]
Line 44:
catch (WebException we)
{
statusCode = ((HttpWebResponse)we.Response).StatusCode; //<-- Line 44
}
Line 489:
if (user.NotifyBySms)
{
Console.WriteLine("Notify user : " + user.Name + " by phone on number: " +
user.PhoneNumber);
string msg = "Alarmen i dit hus er nu deaktiveret. ";
SmsService.Instance.SendSms("lenio", user.PhoneNumber, msg); //<-- Line 489
//Notify user! (alarm now deactive)
}
else
{
Console.WriteLine("Notify user: " + user.Name + "on smartphone");
//Notify user! (alarm now deactive)
}
Line 59:
if (msgHandler(message)) //<-- Line 59
{
Logger.Instance.SaveLog();
try
{
message.Complete();
}
catch (Exception ex)
{
//We might have lost the lock on the message and were too slow to handle it! (Use RenewLock)
}
}
else
{
Logger.Instance.SaveLog();
message.Abandon();
}
The operation timed out exception always follows with nullexception that has this stacktrace:
> lenioServiceBus.exe!lenioServiceBus.Program.AlarmDeactivated(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 507 C#
lenioServiceBus.exe!lenioServiceBus.Program.msgHandler(Microsoft.ServiceBus.Messaging.BrokeredMessage message) Line 109 C#
lenioServiceBus.exe!lenioServiceBus.Program.Main(string[] args) Line 59 C#
[External Code]
Line 507:
catch (Exception ex) //the ex contains the "{"Object reference not set to an instance of an object."} exception
{
Logger.Instance.AddToLog(2, "AlarmDeactivate", "Failed to deactivate alarm on communicationdevice: " + message.Properties["cdId"] + " with exception: " + ex.Message); //<--Line 507
return false;
}
I found out I get this error if I send a message before the other message has completed. I need a solution for this.
If the remote host did not return a response, then the we.Response on line 44 is null, so the attempt to read the StatusCode property will fail (with "object ref not set").
You will need to change your exception handling (line 44) to not always assume that the WebException has a Response.
Perhaps something like:
statusCode = HttpStatusCode.ServiceUnavailable; // set a default
...
try
{
...
}
catch (WebException we)
{
if (we.Response != null)
{
statusCode = ((HttpWebResponse)we.Response).StatusCode;
}
}
You say: "The operation timed out exception always follows with nullexception that has this stacktrace"
The service you are communicating with is limited to processing one request at a time. Whether intentional or not, you probably cannot do anything to "fix" that. My best thought at this time would be a simple lock around the communication in the SendSms() method, so that you only allow one request to communicate at a time. This will probably introduce scalability issues, but would certainly be better than simply failing.
I'm having a hard time tracing an exception within a Task. The message returned from the exception isn't helpful at all. Below is the method that appears to be throwing the exception:
public async Task<bool> TestProxy(IPEndPoint proxy)
{
Ping ping = new Ping();
PingReply reply = await ping.SendPingAsync(proxy.Address);
if (reply == null || reply.Status != IPStatus.Success) return false;
HttpClient client = new HttpClient();
HttpResponseMessage response;
try
{
response = await client.GetAsync("https://google.com");
} catch(Exception ex)
{
return false;
Console.WriteLine(ex.Message);
}
if(response.IsSuccessStatusCode)
{
return true;
}
else
{
return false;
}
And here is the calling code:
public async Task<List<IPEndPoint>> FetchWorkingProxiesAsync()
{
List<IPEndPoint> _proxies = await FetchRawProxiesAsync();
List<IPEndPoint> workingProxies = new List<IPEndPoint>();
Task[] tasks = new Task[_proxies.Count];
for(int i = 0; i < _proxies.Count; i++)
{
IPEndPoint _tmpProxy = _proxies[i];
tasks[i] = Task.Run(async () => {
try
{
if (await TestProxy(_tmpProxy))
{
workingProxies.Add(_tmpProxy);
}
}catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
});
}
await Task.WhenAll(tasks);
return workingProxies;
}
The exception that is being thrown is:
InnerException {"The request was aborted: The request was canceled."} System.Exception {System.Net.WebException}
When I set breakpoints no helpful information is available on the exception. I see that there's a System.Net.WebException but it doesn't say what or why.
I have CLR Throw and User Exceptions ticked in the Exceptions dialogue in VS.
Edit: I just realised I am not using the proxy to test the connection when attempting to connect to google.com. Even so, I'd still like to know how to find out more about the exception thrown.
Is it possible to return a bool and also rethrow an exception within the same method? Ive tried with the following code and it keeps saying that unreachable code is detected or that i cant exit the finally block.
public bool AccessToFile(string filePath)
{
FileStream source = null;
try
{
source = File.OpenRead(filePath);
source.Close();
return true;
}
catch (UnauthorizedAccessException e)
{
string unAuthorizedStatus = "User does not have sufficient access privileges to open the file: \n\r" + filePath;
unAuthorizedStatus += e.Message;
MessageBox.Show(unAuthorizedStatus, "Error Message:");
throw;
}
catch (Exception e)
{
string generalStatus = null;
if (filePath == null)
{
generalStatus = "General error: \n\r";
}
else
{
generalStatus = filePath + " failed. \n\r";
generalStatus += e.Message;
}
MessageBox.Show(generalStatus, "Error Message:");
throw;
}
finally
{
if (source != null)
{
source.Dispose();
}
}
}
Once you throw an exception, processing in your current method finishes and the exception works up the call stack. Either handle your exceptions locally and then return your boolean, or throw them and let them bubble up and handle them at the front end.