Exceptions in a Distributed Environment

In my previous post I covered some of the basics around throwing and handling exceptions.  In this post I’m going to take a look at what happens when an exception occurs during a remoting call.

Remoting Call throwing an Exception

For this example I setup a single server-side object – published through a shared interface and registered for singlecall remoting.

public void ThrowApplicationException()
{
    throw new ApplicationException("Message from the server");
}

My client is a WinForms application with global exception handling.  When I invoke the method the exception is thrown on the server and propagated to the client.

ServerApplicationException

The really cool part is that I even get a full stack trace – including the trace on the server!  Both the server and client also keep running – the exception didn’t cause either of the processes to crash.  Let’s take a look at what happens when we throw some custom exceptions into the mix.

Remote Call throwing a Custom Exception

For this example I have created 2 custom exceptions – the first resides in a shared assembly (reference by both the server and the client) and the other resides only in the server assembly.  They are aptly named SharedException and ServerException.

Let’s see what happens when we throw a new ServerException.

CustomServerException

Not quite what we wanted.  Let’s see what happens when we throw a new SharedException.

CustomSharedException

That’s more like it.  The behaviour here makes perfect sense – the client application receives the serialized information for a ServerException object, but has no way of knowing how to deserialize this object.  The SharedException type also needs to be marked with the Serializable attribute – otherwise this operation would have failed in a similar manner.

Summary

The default behaviour of remoting (propagating exceptions that occur on the server) is very useful – especially in a rich-client environment.  You simply need to ensure that custom exceptions reside in a shared assembly and are serializable – remoting takes care of the rest.

Unfortunately we cannot duplicate this behaviour with WCF applications – the SOA-nature of WCF dictates that all exceptions need to be caught and propagated as faults (which are declared on the service contract).  This is one of the reasons why remoting is probably better suited for rich-client applications than WCF.

Happy coding.