CommunicationException is lifted, even in a try/catch block - c#

I'm currently developping an application for WP7 that needs to make calls to a WCF Service Application. I tested the service with a small WPF application and everything went just fine. But now that I call it from my WP7 app, I systematically get the following exception :
An exception of type 'System.ServiceModel.CommunicationException' occurred in
System.ServiceModel.ni.dll but was not handled in user code
System.ServiceModel.CommunicationException was unhandled by user code
HResult=-2146233087
Message=The remote server returned an error: NotFound.
Source=System.ServiceModel
InnerException: System.Net.WebException
HResult=-2146233079
Message=The remote server returned an error: NotFound.
Source=System.Windows
InnerException: System.Net.WebException
HResult=-2146233079
Message=The remote server returned an error: NotFound.
Source=System.Windows
InnerException:
The exception keeps getting lifted despite the fact I make my service call within a try/catch block like this (in MyProjectPath.Model.User.cs) :
public Task<User> Load(string logon, string pwHash)
{
TaskCompletionSource<User> tcs = new TaskCompletionSource<User>();
client.GetUserByCredsCompleted += ((s, e) =>
{
if (e.Error == null) tcs.TrySetResult(e.Result);
else
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Error encountered while getting data :");
sb.AppendLine(e.Error.Message);
MessageBox.Show(sb.ToString());
}
});
try
{
client.GetUserByCredsAsync(logon, pwHash);
}
catch (System.ServiceModel.CommunicationException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return tcs.Task;
}
And when executed, the exception occurs here (in System.ServiceModel.ni.dll) :
public MyProjectPath.ServiceReference.User EndGetUserByCreds(System.IAsyncResult result) {
object[] _args = new object[0];
// Exception gets lifted by the following line :
MyProjectPath.ServiceReference.User _result = ((MyProjectPath.ServiceReference.User)(base.EndInvoke("GetUserByCreds", _args, result)));
return _result;
}
Did anyone already encountered this problem and solved it ? I must admit I'm pretty clueless here...

You're calling an asynchronous API. Although you're wrapping that call in a try/catch block, that call will presumably be starting up a new thread or queueing a request for another existing thread to pick up. Either way, your try/catch is only protecting you against exceptions thrown on the thread which makes the call, and there aren't any. The (start of) your asynchronous call succeeds just fine, so the catch block never comes into effect, and then control is passed to the other thread and this is where the exception is thrown.
You can't protect against exceptions in EndGetUserByCreds by wrapping your call to GetUserByCredsAsync in a try/catch. The two methods are executing at different times different threads. You need to modify EndGetUserByCreds so that it catches exceptions and deals with them appropriately, rather than letting them crash the thread.

Related

SoapException has the same message but in different forms

We have an ASP.NET project. The project is installed via InstallShield. We have a test method that throws SoapException and compares its message:
internal static string ExceptionMsgCheckForConflicts = "Server was unable to process request. ---> Rethrow exception, look at inner exception ---> System.ArgumentException ---> Item is invalid";
internal static string ErrorMsgCheckForConflictsInvalidException = "Exception should start with 'Server was unable to process request. ---> Rethrow exception, look at inner exception ---> System.ArgumentException ---> Item is invalid'";
[Test]
public void ConflictDetectorItemNotAnItemNode()
{
Assert.Throws<SoapException>(() =>
{
try
{
//Some code that throws SoapException
}
catch (SoapException ex)
{
Assert.IsTrue(ex.Message.StartsWith(ExceptionMsgCheckForConflicts, StringComparison.OrdinalIgnoreCase), ErrorMsgCheckForConflictsInvalidException);
throw;
}
});
}
The code works pretty well. But we decided to run this test on the installed version of project. The problem is that in this case exception is thrown with the message:
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Exception: Rethrow exception, look at inner exception ---> System.ArgumentException: Item is invalid
In fact it is the same message, but contains the names of exceptions. I and my boss have no idea why this happens.
I'm wondering if the odd try / catch / rethrow is causing the problem. Normally, using NUnit, one doesn't catch the exceptions one is asserting on. A simpler way to write the test would be...
var ex = Assert.Throws<SoapException>(() =>
{
// Code that throws SoapException
}
Assert.That(ex.Message.StartsWith(...));
BTW, I couldn't decide whether this was an answer or a comment, but answers make it easier to format code. :-)

Stream Socket error handling winRT

I am working on stream socket,
According to msdn documentaion:
Handling exceptions
You must write code to handle exceptions when you call asynchronous methods on the StreamSocket class. Exceptions can result from parameter validation errors, name resolutions failures, and network errors. Exceptions from network errors (loss of connectivity, connection failures, and server failures, for example) can happen at any time. These errors result in exceptions being thrown. If not handled by your app, an exception can cause your entire app to be terminated by the runtime.
The Windows.Networking.Sockets namespace has features that simplify handling errors when using sockets. The GetStatus method on the SocketError class can convert the HRESULT from an exception to a SocketErrorStatus enumeration value. This can be useful for handling specific network exceptions differently in your app. An app can also use the HRESULT from the exception on parameter validation errors to learn more detailed information on the error that caused the exception.
So I have used following code to handle socket connect error states.
try
{
var socket = new StreamSocket();
HostName host = new HostName("www.google.com");
// connection is executed synchronously
socket.ConnectAsync(host, "2000", SocketProtectionLevel.PlainSocket).AsTask().Wait();
Debug.WriteLine("Success");
}
catch (Exception ex)
{
SocketErrorStatus socketErrorStatus = SocketError.GetStatus(ex.HResult);
switch(socketErrorStatus)
{
case SocketErrorStatus.ConnectionTimedOut:
//do something
break;
case SocketErrorStatus.HostNotFound:
//do something
break;
default:
break;
}
}
But the exception object returned on socket error doesn't contain valid HResult.
Following is resultant exception object:
Count = The name 'InnerExceptionCount' does not exist in the current context
[System.AggregateException]: Count = The name 'InnerExceptionCount' does not exist in the current context
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2146233088
InnerException: {System.Exception: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (Exception from HRESULT: 0x8007274C)}
Message: "One or more errors occurred."
Source: "mscorlib"
StackTrace: " at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)\r\n at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)\r\n at System.Threading.Tasks.Task.Wait()\r\n at StreamSokcetSample.MainPage.Button_Tapped(Object sender, TappedRoutedEventArgs e)"
In this situation I am always getting SocketErrorStatus.Unknown(default value) as result whereas when I pass int value of HRESULT: 0x8007274C to GetStatus, it results in correct output(ConnectionTimedOut = 3).
InnerException: {System.Exception: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (Exception from HRESULT: 0x8007274C)}
Can I rely upon inner exception message and fetch HRESULT from there?
Is there any other way to get desired results?
You are getting an AggregateException since it's being generated from an async method
So yes, you have to check the HResult of InnerException
SocketErrorStatus socketErrorStatus = SocketError.GetStatus(ex.InnerException.HResult);
This will give you desired output.
The root exception is an AggregateException (it is an .NET level exception), it is usually a wrapper exception for exception thrown from another thread. In this case, it is because you used the "ConnectAsync" method which was running in thread pool.
So to get the correct socket status, you should use the InnerException which is throw from the Windows Runtime level.

SqlClient SqlException not caught

I have a Azure worker role perform simple selects on a SQL Azure database. Rarely it throws the following SqlException.
Log
The underlying provider failed on Open. Inner Exception: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Exception Type: System.Data.SqlClient.SqlException
The exception is not caught as a SqlException. It is caught in the generic exception handler. Any suggestions as to why that would be?
try{
}
catch(System.Data.SqlClient.SqlException sqlExcep)
{
}
catch(Exception genericExcep)
{
**//The exception is caught as a generic exception**
}
The SQL Database environment is a layer of routers and proxies that handle network load balancing and resource management. If SQL Database itself didn't timeout, then something else in the middle could have (although that's typically rare).
I usually handle IOException errors as well and treat some of them as a form of transient error. What exception type are you actually receiving?
Did you try implementing the Transient Fault Handling Application Block? http://msdn.microsoft.com/en-us/library/hh680934(v=pandp.50)
Herve
Looks like that's the inner exception, not the actual exception you caught. What is the type of the outer exception? The only thing you can do is catch whichever type the caught exception is, and then inspect the inner exception:
try
{
// Stuff
}
catch (Exception exc)
{
if (exc.InnerException is System.Data.SqlClient.SqlException)
{
var sqlException = exc.InnerException as System.Data.SqlClient.SqlException;
// Do stuff with the error.
}
}
The moral of the story is you can't explicitly catch the inner exception :(
Try Microsoft.Data.SqlClient.SqlException instead of System.Data.SqlClient.SqlException
catch (Microsoft.Data.SqlClient.SqlException ex)
{
}

WCF/C# Unable to catch EndpointNotFoundException

I have created a WCF service and client and it all works until it comes to catching errors. Specifically I am trying to catch the EndpointNotFoundException for when the server happens not to be there for whatever reason. I have tried a simple try/catch block to catch the specific error and the communication exception it derives from, and I've tried catching just Exception. None of these succeed in catching the exception, however I do get
A first chance exception of type
'System.ServiceModel.EndpointNotFoundException'
occurred in System.ServiceModel.dll
in the output window when the client tries to open the service. Any ideas as to what I'm doing wrong?
I was able to replicate your issue and got interested (since I needed the same). I even researched a way to handle \ catch first chance exceptions but unfortunately it is not possible (for managed code) for .net framework 3.5 and below.
On my case I always get a System.ServiceModel.CommunicationObjectFaultedException whenever something gets wrong on the service or whenever I access a down service. It turns out that c#'s using statement is the cause since behind the scene, the using statement always closes the service client instance even if an exception was already encountered (it doesn't jump to catch statement directly).
What happens is that the original exception System.ServiceModel.EndpointNotFoundException will be replaced by the new exception System.ServiceModel.CommunicationObjectFaultedException whenever the using tries to close the service client instance.
The solution i've made is to not use the using statement so that whenever an exception is encountered inside the try block it will instantly throw the exception to the catch blocks.
Try to code something like:
DashboardService.DashboardServiceClient svc = new Dashboard_WPF_Test.DashboardService.DashboardServiceClient();
try
{
svc.GetChart(0);
}
catch (System.ServiceModel.EndpointNotFoundException ex)
{
//handle endpoint not found exception here
}
catch (Exception ex)
{
//general exception handler
}
finally
{
if (!svc.State.Equals(System.ServiceModel.CommunicationState.Faulted) && svc.State.Equals(System.ServiceModel.CommunicationState.Opened))
svc.Close();
}
Instead of:
try
{
using (DashboardService.DashboardServiceClient svc = new Dashboard_WPF_Test.DashboardService.DashboardServiceClient())
{
svc.GetChart(0);
}
}
catch (System.ServiceModel.EndpointNotFoundException ex)
{
//handle endpoint not found exception here (I was never able to catch this type of exception using the using statement block)
}
catch (Exception ex)
{
//general exception handler
}
And you'll be able to catch the right exception then.
Take a look at this post for details on this possible solution. The code shows use of a generate proxy but is valid on ChannelFactory and others as well.
Typical here-be-dragons pattern
using (WCFServiceClient c = new WCFServiceClient())
{
try
{
c.HelloWorld();
}
catch (Exception ex)
{
// You don't know it yet but your mellow has just been harshed.
// If you handle this exception and fall through you will still be cheerfully greeted with
// an unhandled CommunicationObjectFaultedException when 'using' tries to .Close() the client.
// If you throw or re-throw from here you will never see that exception, it is gone forever.
// buh bye.
// All you will get is an unhandled CommunicationObjectFaultedException
}
} // <-- here is where the CommunicationObjectFaultedException is thrown
Proper pattern:
using (WCFServiceClient client = new WCFServiceClient())
{
try
{
client.ThrowException();
}
catch (Exception ex)
{
// acknowledge the Faulted state and allow transition to Closed
client.Abort();
// handle the exception or rethrow, makes no nevermind to me, my
// yob is done ;-D
}
}
Or, as expressed in your question without a using statement,
WCFServiceClient c = new WCFServiceClient();
try
{
c.HelloWorld();
}
catch
{
// acknowledge the Faulted state and allow transition to Closed
c.Abort();
// handle or throw
throw;
}
finally
{
c.Close();
}
This may be a reporting issue for the debugger, rather than not actually catching the exception. this post gives some tips on resolving it, if that is the case... Why is .NET exception not caught by try/catch block?
What is a First Chance Exception?
First chance exception messages most
often do not mean there is a problem
in the code. For applications /
components which handle exceptions
gracefully, first chance exception
messages let the developer know that
an exceptional situation was
encountered and was handled.
Place a try catch block in the CompletedMethod.
An Example:
...
geocodeService.ReverseGeocodeCompleted += ReverseGeocodeCompleted(se, ev);
geocodeService.ReverseGeocodeAsync(reverseGeocodeRequest);
}
private void ReverseGeocodeCompleted(object sender, ReverseGeocodeCompletedEventArgs e)
{
try
{
// something went wrong ...
var address = e.Result.Results[0].Address;
}
catch (Exception)
{ // Catch Exception
Debug.WriteLine("NO INTERNET CONNECTION");
}

Why is this SocketException not caught by a generic catch routine?

Our company provides a network component (DLL) for a GUI application.
It uses a Timer that checks for disconnections. If it wants to reconnect, it calls:
internal void timClock_TimerCallback(object state)
{
lock (someLock)
{
// ...
try
{
DoConnect();
}
catch (Exception e)
{
// Log e.Message omitted
// Raise event with e as parameter
ErrorEvent(this, new ErrorEventArgs(e));
DoDisconnect();
}
// ...
}
}
So the problem is, inside of the DoConnect() routine a SocketException is thrown (and not caught). I would assume, that the catch (Exception e) should catch ALL exceptions but somehow the SocketException was not caught and shows up to the GUI application.
protected void DoConnect()
{
//
client = new TcpClient();
client.NoDelay = true;
// In the following call the SocketException is thrown
client.Connect(endPoint.Address.ToString(), endPoint.Port);
// ... (login stuff)
}
The doc confirmed that SocketException extends Exception.
The stacktrace that showed up is:
TcpClient.Connect() -> DoConnect() -> timClock_TimerCallback
So the exception is not thrown outside the try/catch block.
Any ideas why it doesn't work?
If ErrorEvent really raises another exception (per the comment), then DoDisconnect() is never executed.
Otherwise, the exception you see might be coming form DoDisconnect()
I wrote a little program and was unable to reproduce, a SocketException was caught inside a TimerCallback just fine.
So I suggest you re-think your analysis, the problem may not be what you think it is. A few suggestions:
run it outside the Timer. T|hat takes the threading out of the loop.
run it in the debugger. Where does the exception really occur?
step through the exception handling. Is ErrorEvent doing what it should?
Could you post the DoConnect() code?
Also things to try:
Can you catch it in the DoConnect()?
Try catching the specific exception instead of just the generic.
How does it react if you use debug mode?
Your timClock_TimerCallback isn't called in the same thread as the catch-statement wants to catch an exception. You should catch the exception inside timClock_TimerCallback and then call a method which invokes itself and then rethrow the exception in the right thread.
Not sure this will work, but you could give it a try.

Categories