Prevent Exceptions From WCF Callbacks - c#

I'm making a small chat application. I got to the point where one client sends a message, and then by using callbacks of other clients in the room, they quickly recieve the message. So, if there are 10 people in the room, the service instance of the client who is sending the message, will invoke this in 10 threads:
targetCallback.RecieveMessage(message);
Now, internet connections are volatile, and it could just so happen that it breaks a moment before that's performed, so an exception would be thrown and the client instance automatically destroyed, leaving the message unsent or half-successful.
I found examples that don't really handle those exceptions at all, while other put a simple:
try
{
targetCallback.RecieveMessage(message);
}
catch
{
}
But, is that the best way to handle this exception?

See
http://msdn.microsoft.com/en-us/library/aa354510.aspx
for good advice. Briefly, you should catch TimeoutException and CommunicationException.

I've also seen ObjectDisposedExceptions when calling WCF callbacks, and maybe a SecurityException of some sort, but I can't remember which one.
For applications that need a higher degree of reliability, I write a basic wrapper method that catches all the exceptions and removes that callback from your callback collection. Then I only ever invoke the callback through the wrapper.
Normally I'd also capture some contextual information about the conneciton from the OperationContext like IP address, sessionID and user token so I can identify who failed and log it. But that's left as an exercise to the reader.
public interface ICallbackContract
{
void Operation(string arg);
}
class Program
{
private List<ICallbackContract> Callbacks;
private void SendMessage(string msg)
{
lock (this.Callbacks)
{
foreach (var callback in this.Callbacks)
{
this.InvokeWcf(callback, (c) => c.Operation(msg));
}
}
}
public void InvokeWcf(this ICallbackContract contract, Action<ICallbackContract> op)
{
if (((ICommunicationObject)contract).State != CommunicationState.Opened)
{
lock (this.Callbacks)
Callbacks.Remove(contract);
myLogger.LogError("That contract isn't open! Disconnected.");
return;
}
try
{
op(contract);
}
catch (TimeoutException ex)
{
lock (this.Callbacks)
Callbacks.Remove(contract);
myLogger.LogError("That contract timed out! Disconnected.", ex);
return;
}
catch (CommunicationException ex)
{
...
}
catch (ObjectDisposedException ex)
{
...
}
catch (Exception ex)
}
// Unexpected case.
lock (this.Callbacks)
Callbacks.Remove(contract);
myLogger.FatalError("Something really bad happened!.", ex);
throw;
{
}
}

Related

Correct way to pass errors back to the calling code

I have a function called connect like so:
public boolean connnect(){
{
..... connecting codde
if(connectionSuccessfull)
{
return true;
}
else
{
return false;
}
}
This is a very basic form of error handling, I want to upgrade this function to handle errors correctly. Such as not just tell me false there was an error, but be able to say, error, Authentication failed, or Time-out error etc.
This information then needs to be sent back up the line to the Caller so it can know what happened.
What is the correct way to go about doing this?
{EDIT}
In my care its quite probable that an exception will occur I would say 50% of the time.
I have come up with this, does it look partially correct?
namespace MobileWebServices.Exceptions
{
//Timeout
public abstract class TimeOutException : Exception
{
}
public class ConnectingTimeOutException : TimeoutException
{
}
public class DissconnectingTimeOutException : TimeoutException
{
}
//Authetntication
public abstract class AuthenticationException : Exception
{
}
public class BadAuthenticationException : AuthenticationException
{
}
}
Something along the lines of:
public void Connect()
{
try
{
//code here to look-up the connection details
if(!ValidateConnectionDetails(details))
throw new InvalidOperationException("The connection details are not valid.");
//code here to establish the connection
if(SomeTestThatShowsWereNotHappyWithTheConnection())
throw new Exception("The connection is bad, for some reason");
}
catch(SocketException se)
{
//We'd only have this block if a socket exception is possible. We might just allow it to pass on up.
throw; // User now gets the exception we got, exactly.
//We might re-throw the error, but from here so the stack-trace goes to here rather than the innards of this method:
throw se;
//Most usefully we might throw a new exception that contains this as an inner exception:
throw new Exception("Connecting failed", se);
//Or even better, we might throw a more well-defined exception, that relates to this operation more specifically, with or without the inner exception, depending on whether that is likely to be useful:
throw new ConnectionException("Some message, or maybe just a default is defined in the constructor");
//OR:
throw new ConnectionException("Some message, or maybe just a default is defined in the constructor", se);
}
catch(Exception ex)
{
//If we get to an exception ourselves that isn't of a particular type we're expecting, we probably shouldn't catch it at all. We might though want to note the exception before re-throwing it, or throw a more specific connection with this as an inner-exception:
Log(ex);
throw;
}
}
Because you're no longer returning a value to indicate success, you could also now return an object that represents the connection you created:
public ConnectionObject Connect()
{
// Much as above, but returning the object before the end of the `try`.
}
Returning values representing failure should only be done if that failure is both likely to happen, and something you expect the calling code to be able to reasonably react to right at the point of calling. This isn't that likely with code to connect since the calling code could be code that e.g. connects and then does an operation, and the code calling that in turn is where the exception (whether from here or the subsequent operation) should be caught - it's the code that ultimately cares about the failing.
In the latter case, then returning a value indicating the failure makes a lot more sense. Here though, I'd probably still consider an exception, because it can encapsulate more information, be used by coders in the normal way they use other .NET methods, and because the calling code is probably not written thinking "try to get the connection and then if it works..." it's written thinking "get the connection and then..." with the error case being exactly that; an error case. (For comparison, a method like int.TryParse() is to answer the question "does this string represent an integer, and if so what is it?" where the method int.Parse() answers the question "what is the integer in this string?" with there not being an integer being an error condition).
To think of it another way. Are you currently using a web-browser to browse the web, or are you using it to try to browse the web? Your internet connection could die on you, stopping you from continuing to read these answers, but you'd consider that a problem in what you were trying to do.
The normal approach is to throw an exception (perhaps of a user-defined type), and then to catch those exceptions at a higher level.
If for some reason you cannot use exceptions, you could instead write a wrapper class that encompassed an error message (which would be null if no error occurred) and the bool result (which would only be relevant if the error message is null).
However, I would recommend using exceptions. (The only issue might be whether or not you need to globalise the error message string in the exception, but the consensus is that you should not.)
Here is a sample on how things should be done :
First use your connect() method to return an object (like a Socket for example).
Return a null one if it fails connecting without throwing an Exception.
In your connect() method try/catch your connecting instructions, and rethrow those catched.
Then in the calling method, catch all the Exceptions that can be thrown, and check if the returned object is null or not.
Here is an example of code using Sockets :
public static Socket connect()
{
Socket s = null;
try
{
IPEndPoint iEP = new IPEndPoint("127.0.0.1", 8080);
s = new Socket(iEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
s.Connect(iEP);
if(!s.Connected)
{
return null;
}
}
catch(Exception e)
{
throw e;// Rethrow the Exception to the caller
}
return s;
}
public static void Main(String[] args)
{
Socket mySocket = null;
try
{
mySocket = connect();
}
catch(SocketException e)
{
// TODO - Detailed error about a SocketException
Console.Error.WriteLine("SocketException: " + e.Message + "(" + e.ErrorCode + ")");
}
catch(SecurityException e)
{
// TODO - Detailed error about a SecurityException
Console.Error.WriteLine("SecurityException: " + e.Message);
}
catch(Exception e)
{
// TODO - Detailed error about those Exceptions :
// ArgumentNullException, ObjectDisposedException and InvalidOperationException
Console.Error.WriteLine(e.GetType() + ": " + e.Message);
}
if(mySocket == null)
{
// TODO - Error while initializing the Socket
Console.Error.WriteLine("Error while initializing the Socket");
}
// TODO - Use your Socket here
}
I think the best way is using the try catch exception surrounding your call with the exception you want :
catch(TimeoutException ex)
{
//Do something
}
catch(SqlException ex)
{
//do something
}
//....
catch(Exception ex)
{
//do something
}
Make sure of the order of your catch ( the global Exception in last)

Cannot catch System.Reflection.TargetInvocationException (using TPL)

I have an anonymous TPL task with the following structure:
Task.Factory.StartNew(() =>
{
try
{
DoStuff();
}
catch (OperationCanceledException ex)
{
// process cancellation
}
catch (Exception ex)
{
// process (log) all exceptions
}
finally
{
// tie up various loose ends
}
},
myCancellationToken, // cancellation token
TaskCreationOptions.LongRunning, // always create a new thread
TaskScheduler.Default // default task scheduler
);
Inside of the DoStuff() function, I'm using Spring.NET Social extension for Dropbox to upload a large file to Dropbox. For some reason that I don't yet understand, an exception is being generating during the file upload (via the UploadFileAsync() method call):
(System.Net.Sockets.SocketException (0x80004005): An established connection was aborted by the software in your host machine).
I'm still working out why this exception is happening, but that's not the part that concerns me a present. The bigger problem is that the exception is ultimately wrapped by
System.Reflection.TargetInvocationException and for some strange reason, my try/catch block (in my original code snippet) isn't catching it.
Since I cannot catch the exception, it ultimately crashes the app.
Although I didn't think it should be necessary, I even tried adding an explicit catch block for TargetInvocationException, but again it never fires.
So my question is - how I do I catch this exception, and why isn't it being caught by the constructs shown in my code above?
UPDATE:
This problem appears to have nothing to do with the TPL after all. I modified the call to remove the call to StartNew() so that the code executes synchronously, and I still cannot catch this exception.
I used this code to verify that the TargetInvocationException can be caught:
[Test]
public void TaskExceptionTest()
{
var task = Task.Factory.StartNew(
() =>
{
try
{
throw new TargetInvocationException(null);
}
catch (Exception e)
{
Console.WriteLine("Caught one (inside):" + e.GetType().Name);
}
});
try
{
task.Wait();
}
catch (AggregateException ae)
{
// Assume we know what's going on with this particular exception.
// Rethrow anything else. AggregateException.Handle provides
// another way to express this. See later example.
foreach (var e in ae.InnerExceptions)
{
if (e is TargetInvocationException)
{
Console.WriteLine("After:" + e.GetType().Name);
}
else
{
throw;
}
}
}
}
You can read here about exception handling and tasks.

Continue after try-catch-finally

This might sound like a weird question but I don't get it...
Let's say I have an application which connects to a server to do some stuff. This connect might fail and throw an exception which I can catch.
try {
Client.connect();
} catch (System.Exception ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
However, in case that the connect is succcesful the application shall continue...
try {
Client.connect();
} catch (System.Exception ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
// Talk to the server...
The "server talking" however is executed in any case. It doesn't matter if the exception occured or not.
How can I make sure that the "server talking" is only executed if the connect was successful? Do I have to move all of the following code inside the trystatement? What is a clean way to program such a behavior?
"Talk to the server" should happen in the try block, right after
Client.connect();
The easiest way is to just set a boolean. But there are many many many ways to deal with this.
bool connectionError = false;
try {
// connect
} catch (...) {
connectionError = true;
} finally {
// whatever
}
if (!connectionError) {
// talk to server.
}
Have another variable like clientConnected and set it to true right after Client.Connect(). Then outside the try-catch check for clientConnected before talking to the server.
Avoid doing everything in a single try-catch. You should use separate try-catch blocks for different actions that might throw exceptions, and catch specific exceptions as much as possible.
Typically you use try...catch statements for those statements which you expect to throw an Exception. Try...Catch defines its own scope, so you should declare any variables outside of the Try...Catch block (at least, those variables that you want to use outside of it).
If you want to know if an exception was thrown, then define the Exception variable above the Try...Catch. You can then examine it to determine if it is Null or not.
System.Exception ex;
try {
Client.connect();
} catch (ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
if (ex != null){ ... }
// Talk to the server...
You could log an event and then call some code to either try again or to cancel... or whatever you need to do.
Use some type of flag variable to indicate whether server is connected or not. If your method is returning a boolean variable then also it is ok.
int flag=0;
while(flag==0){
try {
Client.connect();
flag=1;
} catch (System.Exception ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
}
//If server connects code

Correct way to close WCF 4 channels effectively

I am using the following ways to close the WCF 4 channels. Is this right way to do it?
using (IService channel
= CustomChannelFactory<IService>.CreateConfigurationChannel())
{
channel.Open();
//do stuff
}// channels disposes off??
That used to be the commonly accepted way to release WCF client proxies in the "early" days of WCF.
However things have since changed. It turned out that the implementation of IClientChannel<T>.Dispose() simply invokes the IClientChannel<T>.Close() method, which may throw an exception under some circumstances, such as when the underlying channel isn't open or can't be closed in a timely fashion.
Therefore it's not a good idea to invoke Close() within a catch block since that may leave behind some unreleased resources in case of an exception.
The new recommended way is to invoke IClientChannel<T>.Abort() within the catch block instead, in case Close() would fail. Here's an example:
try
{
channel.DoSomething();
channel.Close();
}
catch
{
channel.Abort();
throw;
}
Update:
Here's a reference to an MSDN article that describes this recommendation.
Although not strictly directed at the channel, you can do:
ChannelFactory<IMyService> channelFactory = null;
try
{
channelFactory =
new ChannelFactory<IMyService>();
channelFactory.Open();
// Do work...
channelFactory.Close();
}
catch (CommunicationException)
{
if (channelFactory != null)
{
channelFactory.Abort();
}
}
catch (TimeoutException)
{
if (channelFactory != null)
{
channelFactory.Abort();
}
}
catch (Exception)
{
if (channelFactory != null)
{
channelFactory.Abort();
}
throw;
}

C# try..catch - redirecting error handling flow from one catch to the next

I have a try..catch block that looks like this:
try
{
...
}
catch (IOException ioEx)
{
...
}
catch (Exception ex)
{
...
}
I'd like to handle just a certain kind of IOException, namely a sharing violation (Win32 0x20). Other IOExceptions and all other Exception descendants should be handled generally by the second catch-all catch.
Once I know that the IOException is not a sharing violation, how can I cleanly redirect the error handling flow to the general catch? If I rethrow in catch (IOException) the second catch does not invoke. I know I can nest try..catches but is there a cleaner way?
EDIT: On factoring-out handler logic
Factoring repeated code in methods will surely work, but I noticed that in general when you use factored methods for exception handling it tends to have subtle problems.
First of all, a catch clause has direct access to all of the local variables prior to the exception. But when you "outsource" exception handling to a different method then you have to pass the state to it. And when you change the code so does the handler method's signature changes, which might be a maintainability issue in more complicated scenarios.
The other problem is that program flow might be obscured. For example, if the handler method eventually rethrows the exception, the C# compiler and code analyzers like Resharper don't see it:
private void Foo()
{
string a = null;
try
{
a = Path.GetDirectoryName(a);
System.Diagnostics.Debug.Print(a);
}
catch (Exception ex)
{
HandleException(ex, a); //Note that we have to pass the "a"
System.Diagnostics.Debug.Print(
"We never get here and it's not obvious" +
"until you read and understand HandleException"
);
...!
}
}
static void HandleException(Exception ex, string a)
{
if (a != null)
System.Diagnostics.Debug.Print("[a] was not null");
throw (ex); //Rethrow so that the application-level handler catches and logs it
}
VS
private void Bar()
{
string a = null;
try
{
a = System.IO.Path.GetDirectoryName(a);
System.Diagnostics.Debug.Print(a);
}
catch (Exception ex)
{
if (a != null)
System.Diagnostics.Debug.Print("[a] was not null");
throw; //Rethrow so that the application-level handler catches and logs it
System.Diagnostics.Debug.Print(
"We never get here also, but now " +
"it's obvious and the compiler complains"
);
...!
}
}
If I want to avoid these kind of (minor) problems then it seems that there is no cleaner way than nesting try..catch blocks, as Hank pointed out.
Just factor the handling logic into a separate method.
try
{
...
}
catch (IOException ioEx)
{
if (sharing violation)
HandleSharingViolation();
else
HandleNonsharingViolation();
}
catch (Exception ex)
{
HandleNonsharingViolation();
}
Or test the exceptions yourself
catch (Exception ex)
{
if (ex is IOException && ex.IsSharingViolation()
HandleSharingViolation();
else
HandleNonsharingViolation();
}
No, you'll have to nest.
Once you are in 1 of the catch blocks, this 'try' is considered handled.
And I think it may make a lot of sense, "sharing violation" sounds like a special case that probably isn't so tightly coupled to the rest as you might be thinking. If you use nest try-catch, does the try block of the special case has to surround the exact same code? And of course it's a candidate to refactor out as a separate method.
Create Method to handle exception, pass the exception to that method , based on the type Handle the exception in the way you want.Call these method in both these blocks.
Use nested try catch blocks.
try
{
try
{
}
catch (IOException ioEx)
{
if (....)
else
throw;
}
}
catch
{
}
what about "finally"?
you can first set a 'variable' in the IOException block once you know the IOException is not sharing violation. Then, in your finally block, if that 'variable' is set, you proceed to do whatever you need to do.
Below impl. tested and confirmed.
bool booleanValue = false;
try
{
test1(); // this would thro IOException
}
catch (IOException e)
{
booleanValue = true; // whatever you need to do next
}
finally
{
if (booleanValue)
{
Console.WriteLine("Here");
}
}
Tryout this nested block
try
{
}
catch(Exception ioex)
{
try
{
}
catch(Exception ex)
{
}
}

Categories

Resources