ExceptionManager Find Policy by Message?

Topics: Exception Handling Application Block
Apr 21, 2009 at 7:44 PM
It appears that the Exception policies are found by type.  Is there a way to filter based on the message of a thrown type?
Apr 22, 2009 at 2:57 AM
No support for that.  The exceptionpolicy entries are stored within a collection of Dictionary<Type, ExceptionPolicyEntry>.


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Apr 22, 2009 at 10:40 AM
Edited Apr 22, 2009 at 1:23 PM

I am trying to implement WCF Exception Shielding using the Enterprise Library Exception Handling Application Block.

 

My config file looks like this

 

<exceptionHandling>

    <exceptionPolicies>

      <add name="WCF Exception Shielding">

        <exceptionTypes>

          <add type="System.DivideByZeroException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

            postHandlingAction="ThrowNewException" name="DivideByZeroException">

            <exceptionHandlers>

              <add exceptionMessage="Test" faultContractType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

                type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

                name="DefaultFaultContract Handler">

                <mappings>

                  <add source="{Guid}" name="FaultID" />

                  <add source="{Message}" name="FaultMessage" />

                </mappings>

              </add>

            </exceptionHandlers>

          </add>

        </exceptionTypes>

      </add>

    </exceptionPolicies>

  </exceptionHandling>

 

<serviceDebug includeExceptionDetailInFaults="false" />

 

 

On the WCF side my interface looks like this

 

using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF;   

 

namespace WCFException

{

[ServiceContract]

[ExceptionShielding]

      public interface IService1

      {

 

        [OperationContract]

        [FaultContract(typeof(WCFServiceFault))]

        string GetMessage();

 

        // TODO: Add your service operations here

      }

 

[DataContract]

public class WCFServiceFault

      {

        private string _faultMessage;

        private Guid _faultID;

 

        [DataMember]

        public string FaultMessage

        {

            get { return _faultMessage; }

            set { _faultMessage = value; }

        }

        [DataMember]

        public Guid FaultID

        {

            get { return _faultID; }

            set { _faultID = value; }

        }

      }

}

 

The implementation of the GetMessage Method

 

public string GetMessage()

        {

 

            try

            {

                int i, j, k;

                j = 1;

                k = 0;

                i = j / k;

            }

            catch (Exception exp)

            {

                throw new DivideByZeroException();

                //WCFServiceFault fault = new WCFServiceFault();

                //throw new FaultException<WCFServiceFault>(fault);

            }

            return "No Error";

        }

 

 

The implementation of the Client Side Code that is calling this Service is as

       

Service1Client serviceProxy = new Service1Client();

private void cmdMessage_Click(object sender, EventArgs e)

        {

             try

            {

                string strMessage = serviceProxy.GetMessage();

            }

            catch (FaultException<WCFServiceFault> exception)

            //catch (Exception exception)

            {

                //WCFServiceFault serviceFault = new WCFServiceFault();

                WCFServiceFault serviceFault = exception.Detail;

                MessageBox.Show(serviceFault.FaultMessage);

                MessageBox.Show(serviceFault.FaultID.ToString());

 

            }

        }

 

 

When I run the above code I get a runtime Error saying

 

  System.ServiceModel.CommunicationException was unhandled

  Message="The underlying connection was closed: The connection was closed unexpectedly."

  Source="mscorlib"

  StackTrace:

   

 

 

Can you please help me on this so that I am able to catch the DivideByZeroException and show the Message as  “Test” (as in config file) in this case along with FaultID.

 

Please advise.

Apr 22, 2009 at 11:07 AM
Edited Apr 22, 2009 at 11:09 AM
Why is your faultContractExceptionType specified as FaultContractExceptionHandler and not the WCFServiceFault?


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Apr 23, 2009 at 1:12 PM
Edited Apr 23, 2009 at 1:36 PM
Sarah Thanks for the quick response.
This helped me in indentifying the problem I changed my config file to 

<

 

add exceptionMessage="test" faultContractType="WCFException.WCFServiceFault, WCFException, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

 

 

 

type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

 

 

 

name="DefaultFaultContract Handler">

 

 

 

and the code at client side 
  try

            {

                string strMessage = serviceProxy.GetMessage();

            }

            catch (FaultException<WCFServiceFault> exception)

            //catch (Exception exception)

            {

                //WCFServiceFault serviceFault = new WCFServiceFault();

                WCFServiceFault serviceFault = exception.Detail;

                MessageBox.Show(serviceFault.FaultMessage);

                MessageBox.Show(serviceFault.FaultID.ToString());

            }

 

 

showed me the error message "Attempt to divide by zero" along with the FaultID.

I have two questions

1. Why did it not give me the message "test" as specified in the config file ?
2. How do we handle System level exceptions say when my service got timed out ( like TimeOut Exceptions) e.g when the service is down .  

Regards,
Dhirendra Trivedi
Apr 24, 2009 at 3:22 AM
1.  It's because you added the mapping entry:    <add source="{Message}" name="FaultMessage" />  The "test" message is in the exception.Message. 
2.  I'm not an expert in WCF so I can't give you any personal tips so I'll just refer you to these links:
     http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/f5168400-8a84-4352-9a09-56077475ccc5
     http://www.codeproject.com/KB/WCF/WCF_Operation_Timeout_.aspx


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Apr 24, 2009 at 2:52 PM

Hi Sarah,

Thanks for the response.  I have one more Enterprise Library related query.  Currently if you look at my config file then it is only configurable to handle DivideByZeroException. 

<add name="WCF Exception Shielding">

        <exceptionTypes>

          <add type="System.DivideByZeroException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

            postHandlingAction="ThrowNewException" name="DivideByZeroException">

            <exceptionHandlers>

              <add exceptionMessage="test" faultContractType="WCFException.WCFServiceFault, WCFException, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

                type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

                name="DefaultFaultContract Handler">

                <mappings>

                  <add source="{Guid}" name="FaultID" />

                  <add source="Message" name="FaultMessage" />

                </mappings>

              </add>

            </exceptionHandlers>

          </add>

 

Now suppose I want to add other types of exceptions say

IndexOutOfRangeException, InvalidOperationException, etc in my application so I added one more policy to handle IndexOutOfRangeException. 

 

My config file becomes  i.e. (below section is appended below the </add> tag above).

 

<add name="WCF Policy">

        <exceptionTypes>

          <add type="System.IndexOutOfRangeException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

            postHandlingAction="ThrowNewException" name="IndexOutOfRangeException">

            <exceptionHandlers>

              <add exceptionMessage="Array out of range." faultContractType="WCFException.WCFServiceFault, WCFException, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

                type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

                name="Fault Contract Exception Handler">

                <mappings>

                  <add source="{Guid}" name="FaultID" />

                  <add source="{Message}" name="FaultMessage" />

                </mappings>

              </add>

            </exceptionHandlers>

          </add>

 

I then modified my earlier method as below

 

 

public string GetMessage()

        {

int[] numbers;

            numbers = new int[10];

 

            int x;

 

            x = numbers[12];

 

            int i, j, k;

            i = 1;

            j = 0;

            k = i / j;

 

            return "No Error";       

      }

 

And when I ran this code it gave me error “Communication Exception Unhandled”.  This implies that the code generated error at line x = numbers[12]; which was unhandled.

 

What changes do I need to make so that the code is able to handle multiple exceptions?  In this scenario both IndexOutOfRangeException and Divide by Zero Exception.

 

Regards,

Dhirendra Trivedi

Apr 27, 2009 at 9:11 AM
Hi,

In your exception policy in the config which is the "WCF Exception Shielding", You can simply add new exception type. In your case, you just need to add the IndexOutOfRangeException type.

Valiant Dudan
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com