SoapExceptions

Jan Tielens in his blog brought up an approach http://weblogs.asp.net/jan/posts/27835.aspx he used to create SoapExceptions. The code/concept is similar to something I wrote here where I am working. However, we added a twist that I thought was kindof interesting and worth sharing. Specifically, our web services are basically a service facade into an underlying business tier. This is nothing new to anyone. We also make it a point to say that all exceptions emanating from our business tier are derived from ApplicationException and defined also within our tier. This means that we have total control of the definition of all of our exceptions. Again, a relatively common practice and probably nothing new to many of you.

Now, since we own the definitions of all of these exceptions, we created several custom attributes that let us use a SoapFactory I wrote to create a SoapException from any of our Business Exceptions. This simplifies our WebMethod code tremendously. For example:

CybralSoapErrorCode is an attribute that allows me to populate the detail block of a SoapException with a common key defined in the enumeration ProfileSoapKeys. By using an enumeration to fill in the key and providing it in the Attribute I can do typechecking to make sure that there are no misspellings. This means that I don't have to worry about misspellings in my keys and a client can be certain that I did spell it right when they evaluate the Detail block in order to figure out any application specific error information ( a small thing but worth the trouble ) (Also using the Enumeration was the idea of a coworker of mine. He had a bug where a misspelling occurred and he vowed he never wanted it to happen again;):

Now the CybralSoapException factory method code looks like this:publicstatic CybralSoapException Create( Exception ex ){MemberInfo info = ex.GetType();// get the errorCodeobject[] attributes = info.GetCustomAttributes( typeof( CybralSoapErrorCodeAttribute ), false );Enum errorCode = (attributes.Length > 0) ? ((CybralSoapErrorCodeAttribute)attributes[0]).ErrorCode : CybralSoapExceptionKeys.UnexpectedSystemError;// get the faultCodeattributes = info.GetCustomAttributes( typeof( CybralSoapFaultCodeAttribute ), false );XmlQualifiedName faultCode = (attributes.Length > 0) ? ((CybralSoapFaultCodeAttribute)attributes[0]).FaultCode : SoapException.ServerFaultCode;// THIS CONTRUCTOR MERELY FORMATS THE DETAIL BLOCK FOR ME.// Also this class is derived from SoapException which means it gets caught correctly by all clients as a SoapException// Of course it will lose all reference to CybralSoapException and will be formatted as a regular SoapException, but thats ok.returnnew CybralSoapException ( ex.Message, faultCode, errorCode, System.Web.HttpContext.Current.Request.Path, ex );}I could get into the code of the attributes, but I am starting to annoy myself with the length of this blog. As always, feedback is appreciated.