ExceptionHandling block 3.1 error with ThrowNewException replace handler

Topics: Enterprise Library Core, Exception Handling Application Block, General discussion
Jun 3, 2010 at 9:02 PM
Edited Jun 4, 2010 at 12:22 AM

I have a WCF service that uses a data access layer and I intentionally used a sp name that does not exists to have a SqlException thrown.

I configured Ent LIbrary in web.config of the WCF and installed in GAC the ent lib dlls.

<configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

</configSections>

<exceptionHandling>
    <exceptionPolicies>


      <add name="DALPolicy">
        <exceptionTypes>
          <add type="System.Data.SqlClient.SqlException, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
            postHandlingAction="ThrowNewException" name="SqlException">
            <exceptionHandlers>
              <add exceptionMessage="An exception occured in Data Acces Layer. Please check DAL logs using the following identifier: {handlingInstanceID}"
                exceptionMessageResourceType="" replaceExceptionType="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                name="Replace Handler" />
            </exceptionHandlers>
          </add>
          <add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
            postHandlingAction="NotifyRethrow" name="Exception" />
        </exceptionTypes>
      </add>
     
    </exceptionPolicies>
  </exceptionHandling>

and this is my handling code in the DAL layer:

catch (SqlException ex)
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, "DALPolicy");
                if (rethrow)
                    throw;
            }

when it gets to ExceptionPolicy.HandleException(ex, "DALPolicy"); it throws an unhandled exception:

System.Exception was unhandled by user code
  Message="An exception occured in Data Acces Layer. Please check DAL logs using the following identifier: 674a8abb-1805-4ed4-add0-36c590a8806d"
  Source="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"
  StackTrace:
       at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicyEntry.IntentionalRethrow(Exception chainException, Exception originalException)
       at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicyEntry.RethrowRecommended(Exception chainException, Exception originalException)
       at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicyEntry.Handle(Exception exceptionToHandle)
       at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicyImpl.HandleException(Exception exceptionToHandle)
       at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.HandleException(Exception exceptionToHandle, String policyName, ExceptionPolicyFactory policyFactory)
       at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.HandleException(Exception exceptionToHandle, String policyName)
       at DataLayer.ManagerSubordinatesDAL.GetSubordinates(Int32 employeeid) in C:\FunStoreBS\FunStoreTwo\DataLayer\ManagerSubordinates.cs:line 109
       at WcfOrderServices.ManagerSubordinates.PutSubordinatesInCache(Int32 employeeId) in C:\FunStoreBS\FunStoreTwo\WcfOrderServices\ManagerSubordinates.svc.cs:line 143
       at WcfOrderServices.ManagerSubordinates.GetSubordinates(Int32 employeeId) in C:\FunStoreBS\FunStoreTwo\WcfOrderServices\ManagerSubordinates.svc.cs:line 123
       at SyncInvokeGetSubordinates(Object , Object[] , Object[] )
       at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
       at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
  InnerException:

so it does not get to execute the code:

if (rethrow)
  throw;

I used before logging and was working.

I used PostHandlingAction = None and it does not throw, only when ThrowNewException or NotifyRethrow the block throws exception

I do not understand why

 

 

Jun 4, 2010 at 12:51 AM

Using None as the PostHandlingAction means you don't want to do anything when you encountered an exception, even if you used a replace handler.  ThrowNewException and NotifyRethrow are, as you observed, causes the exception to be thrown.  If you want to throw the exception specified in the replace handler, use ThrowNewException and in your code, make use of the overload of the HandleException method which takes an out Exception parameter.

catch (SqlException ex)
            {

               Exception newException = null;
                bool rethrow = ExceptionPolicy.HandleException(ex, "DALPolicy" out newException);
                if (rethrow)
                    throw newException;
            }

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@Avanade.com

Jun 4, 2010 at 1:28 AM

HI Sarah,

 

Thank you for your answer. It still throws an exception.

Now it is not at the bool rethrow = ExceptionPolicy.HandleException(ex, "DALPolicy" out newException);

but at the throw newException;

I copied the code exactly as you told me to do. Bellow is the error

 

 

System.Exception was unhandled by user code
  Message="An exception occured in Data Acces Layer. Please check DAL logs using the following identifier: df955d7a-dabf-4d59-961b-4a7307a4f133"
  Source="DataLayer"
  StackTrace:
       at DataLayer.ManagerSubordinatesDAL.GetSubordinates(Int32 employeeid) in C:\FunStoreBS\FunStoreTwo\DataLayer\ManagerSubordinates.cs:line 113
       at WcfOrderServices.ManagerSubordinates.PutSubordinatesInCache(Int32 employeeId) in C:\FunStoreBS\FunStoreTwo\WcfOrderServices\ManagerSubordinates.svc.cs:line 143
       at WcfOrderServices.ManagerSubordinates.GetSubordinates(Int32 employeeId) in C:\FunStoreBS\FunStoreTwo\WcfOrderServices\ManagerSubordinates.svc.cs:line 123
       at SyncInvokeGetSubordinates(Object , Object[] , Object[] )
       at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
       at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
  InnerException:

 

Jun 4, 2010 at 1:51 AM

Yes it will.  Ok, I forgot this is a WCF application, so you want to be able to handle the exception in the client, right?  If yes, you need to make use of the FaultContractWrapperExeptionHandler.  Here's a useful link - http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/04/07/Shielding-WCF-Services-with-Exception-Handling-Application-Block-_2D00_-Part-1.aspx

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@Avanade.com

Jun 13, 2010 at 1:34 AM

Hi

Thanks for the example.

It does not return a FaultException<T> to the client, merely a normal exception

 

I even tried to use the Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF without the strong name in the web.config I get to the client an Exception like this

Unrecognized element 'mappings'.  .[..../]WcfOrderServices\web.config line 119

Server stack trace:
   at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:

 

Thanks

Jun 15, 2010 at 2:10 PM
Edited Jun 15, 2010 at 2:13 PM

Hi,

Have you been able to verify from the example posted by Sarah if there are any differences with the implementation between yours? Also, could you send us a copy (entlib.support@avanade.com) of your sample app so that we can take a closer look and try to reproduce it from our end. Thanks.

Gino Terrado
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com