0

I have these three packages loaded to my WCF service project:

EnterpriseLibrary.Common Version 6.0.1304.0
EnterpriseLibrary.ExceptionHandling 6.0.1304.0
EnterpriseLibrary.ExceptionHandling.WCF Version 6.0.1304.0

Here is the service interface and MyTestFault DataContract:

[ServiceContract]
public interface IRepairService
{
    [OperationContract]
    [FaultContract(typeof(MyTestFault))]
    string SaveRepairCode(string failureCode, string description);
}

[DataContract]
public class MyTestFault
{
    #region Member Fields

    private string _message = "An unexpected error occured while executing the service method.";

    #endregion

    #region Properties

    [DataMember]
    public string Message
    {
        get { return _message; }
        set { _message = value; }
    }

    #endregion

    #region Constructor(s)

    public MyTestFault() { }

    #endregion
}

Here is the implementation of the service:

[ExceptionShielding("TestPolicy")]
public class RepairService : IRepairService
{
    #region Private members

    private WimDAL wimDAL;
    ExceptionManager exManager;

    #endregion

    #region Constructor(s)

    public RepairService()
    {
        wimDAL = new WimDAL();

        var testPolicy = new List<ExceptionPolicyEntry>
        {
            {
                new ExceptionPolicyEntry(
                    typeof(SqlException), 
                    PostHandlingAction.ThrowNewException, 
                    new IExceptionHandler[]
                    {
                        new FaultContractExceptionHandler(
                            typeof(MyTestFault), 
                            "SqlException Occurred.",
                            new NameValueCollection(){ { "Message", "Message" }})
                    }) 
            },
            {
                new ExceptionPolicyEntry(
                    typeof(Exception), 
                    PostHandlingAction.ThrowNewException, 
                    new IExceptionHandler[]
                    {
                        new FaultContractExceptionHandler(
                            typeof(MyTestFault), 
                            "Exception Occurred.",
                            new NameValueCollection(){ { "Message", "Message" }})
                    }) 
            }
        };

        var policies = new List<ExceptionPolicyDefinition>();
        policies.Add(new ExceptionPolicyDefinition(
            "TestPolicy", testPolicy));

        exManager = new ExceptionManager(policies);
    }

    #endregion

    /// <summary>
    /// Insert a new fail code with description into RPCODE.
    /// Duplicate primary key will throw SqlException that should be processed by EHAB
    /// </summary>
    public string SaveRepairCode(string failureCode, string description)
    {
        using (TransactionScope txScope = new TransactionScope())
        {
            WimSQLCommand sc = new WimSQLCommand() { StoredProcedure = "Repair.RPCODE_Insert" };

            sc.Parameters.Add(new SqlParameter("@FailureCode", failureCode));
            sc.Parameters.Add(new SqlParameter("@Desc", description));

            exManager.Process(() => wimDAL.Execute_NonQueryNoReturn(sc), "TestPolicy");

            txScope.Complete();
            return "<Save_Repair_Code></Save_Repair_Code>";
        }
    }
}

Now, I have a TestClient console application that is part of the same project that has a reference to the project and a service reference. From there I call the SaveRepairCode() method and try to catch the specific fault exception like so:

ServiceReference1.RepairServiceClient r = new ServiceReference1.RepairServiceClient();

Console.WriteLine("Enter a new repair code:");
string repairCode = Console.ReadLine();
Console.WriteLine("Enter description:");
string description = Console.ReadLine();

try
{
    r.SaveRepairCode(repairCode, description);
}
catch (FaultException<MyTestFault> ex)
{
    //do something
    throw;
}
catch (FaultException fex)
{
    //do something
    throw;
}

Finally, I run the console app and try to save a duplicate repair code. I know through debugging that this causes the SqlException to occur. After I step over the SqlException, I see the "FaultContractWrapperException was unhandled by user code" exception and it has the message I specified in the policy of "SqlException occurred.". When I step over that I get back to the client and see this error:

CommunicationException was unhandled
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.

PS - this is Enterprise Library 6 with WCF and I made no manual changes to the web.config... and yes, includeExceptionDetailInFaults is set to false.

What am I missing here? Thanks in advance.


UPDATE
Looks like I was missing this one line of code after instantiating the new ExceptionManager.

ExceptionPolicy.SetExceptionManager(exManager);

Nice to see that this one line of code is NOT in the Enterprise Library 6 - April 2013.chm but it IS in the "Developer's Guide to Microsoft Enterprise Library-Preview.pdf" on page 90 of 269. After including that one line I get into the proper FaultException catch on the client.

With that being said, I still can't get other MyTestFault properties on the client. For example, if I add public string StoredProcedureName to MyTestFault and map it to the SqlException's "Procedure" property, I always see null on the client. The only change in the policy for this would be to add the mapping like so:

new NameValueCollection(){ { "Message", "{Message}" }, { "StoredProcedureName", "{Procedure}" } }
BBauer42
  • 3,549
  • 10
  • 44
  • 81

1 Answers1

0

It turns out this line was the culprit.

exManager.Process(() => wimDAL.Execute_NonQueryNoReturn(sc), "TestPolicy");

Insead of using the ExceptionManager's Process method, just execute the command you expect a potential exception for like so.

wimDAL.Execute_NonQueryNoReturn(sc);

This does not follow what the "Developer's Guide to Microsoft Enterprise Library-Preview.pdf" says but I guess the documentation is still a work in progress. I hope this helps someone else.

BBauer42
  • 3,549
  • 10
  • 44
  • 81