Advanced usage

Error handling

Basing on the Basic usage server-side implementation of the service
Let's take a look at the following client-side service call,
when we're expecting the ArgumentNullException to be thrown:

/* null value as parameter */
CompositeType response2 = client.getDataUsingDataContract(null);
Depending on the IncludeExceptionDetailInFaults flag in the Web.config file on the server-side
  • when the flag is off, the code execution will result
Exception in thread "main" com.svconnect.exceptions.FaultException: InternalServiceFault
The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.
  • when the flag is on, the output console will show
Exception in thread "main" com.svconnect.exceptions.FaultException: InternalServiceFault
Value cannot be null.
Parameter name: composite
Although error messages passing works well and is sufficient enough for most of applications,
there is more elegant and expandable way to handle error between Java and C# WCF service

Let's modify the service implementation on the server-side first
by adding a custom class of fault contract

[ServiceContract]
public interface IService1
{
    [OperationContract]
    string GetData(int value);

    [OperationContract]
    [FaultContract(typeof(ServiceData))]
    CompositeType GetDataUsingDataContract(CompositeType composite);
}

// Custom contract for error handling
[DataContract]
public class ServiceData
{
    [DataMember]
    public bool Result { get; set; }
    [DataMember]
    public string ErrorMessage { get; set; }
    [DataMember]
    public string ErrorDetails { get; set; }
}
Let's now modify slightly the implementation

public CompositeType GetDataUsingDataContract(CompositeType composite)
{
    if (composite == null)
    {
        ServiceData myServiceData = new ServiceData();
        myServiceData.Result = false;
        myServiceData.ErrorMessage = "unforeseen error occured. Please try later.";
        myServiceData.ErrorDetails = "some details";
        throw new FaultException<ServiceData>(myServiceData, myServiceData.ErrorMessage);
    }
    if (composite.BoolValue)
    {
        composite.StringValue += "Suffix";
    }
    return composite;
}

After recreating the service reference and regenerating client classes the call
CompositeType response2 = client.getDataUsingDataContract(null);
must be surrounded from now on with try-catch block of code catching Exception of ServiceData type

As a result, changes on the server-side forced generator to create one more class - ServiceData which inherits from java.lang.Exception and is present in throws clause regarding to the getDataUsingDataContract method.
This approach is definitely much more acceptable by Java developers and checked-exceptions fans

Last edited Oct 15, 2012 at 2:18 PM by marochm, version 6

Comments

No comments yet.