FaultContractWrapperException

Topics: Exception Handling Application Block
Jul 17, 2008 at 6:31 PM
Edited Jul 17, 2008 at 10:05 PM
Hi,

I am trying to configure Exception Application Block.. When I tried following scenario, app throws an exception:

My Config file: ( summary: Two policies.. One ""WCF Exception Shielding" which handled all unhandled exception in middleware( it logs and replaes with fault contract .. Second "ReplaceWithFault" to replace sql exception in to Fualtcontract.)

<exceptionHandling>

    <exceptionPolicies>

      <add name="ReplaceWithFault">  

        <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="ExceptionToFault" faultContractType="FaultContracts.FaultErrorMessageWithCode, Services.FaultContracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

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

                name="Fault Contract Exception Handler">  

                <mappings>

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

                </mappings>

              </add>

            </exceptionHandlers>

          </add>

        </exceptionTypes>

      </add>

      <add name="WCF Exception Shielding">  

        <exceptionTypes>

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

            postHandlingAction="ThrowNewException" name="Exception">  

            <exceptionHandlers>

              <add logCategory="General" eventId="100" severity="Error" title="Services.ExceptionHandling"

                formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

                priority="0" useDefaultLogger="false" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

                name="Logging Handler" />  

              <add exceptionMessage="ExceptionShielding" faultContractType="FaultContracts.FaultErrorMessageWithCode, Services.FaultContracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

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

                name="Fault Contract Exception Handler">  

                <mappings>

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

                </mappings>

              </add>

            </exceptionHandlers>

          </add>

          <add type="System.ServiceModel.FaultException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

            postHandlingAction="None" name="FaultException" />  

        </exceptionTypes>

      </add>

    </exceptionPolicies>

  </exceptionHandling>

 

 

 

 

 

 

 

 

 

Here is the code I am using in a method to use ""ReplaceWithFault" policy

 

 

 

 

 

 

 

 

 

        catch (System.Data.SqlClient.SqlException ex)

            {

              if (ExceptionPolicy.HandleException(ex,"ReplaceWithFault"))

                {

                    throw;

                }

 

            }



Here is the Exception message I am getting:

Timestamp: 7/17/2008 6:16:59 PM

Message: HandlingInstanceID: f7595606-6b68-4e3e-bb9a-0b5a5de83689

An exception of type 'Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractWrapperException' occurred and was caught.

-----------------------------------------------------------------------------------------------------------------------------------------

07/17/2008 14:16:59

Type : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractWrapperException, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

Message : ExceptionToFault

Source : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling

Help link :

FaultContract : .Services.FaultContracts.FaultErrorMessageWithCode

Data : System.Collections.ListDictionaryInternal

TargetSite : System.Exception IntentionalRethrow(System.Exception, System.Exception)

Stack Trace :    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)

   at .Services.ServiceImplementation.AppServices.AddCompany(AddCompanyRequest request) in D:\SAI\Dev\ServiceLayer\.Services\Source\Service Interface\.Services.ServiceImplementation\AppServices.cs:line 91

   at SyncInvokeAddCompany(Object , Object[] , Object[] )

   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)

   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)

   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)

   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)

   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)

   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)

   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)

   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

 

Additional Info:

 

MachineName : SQL1

TimeStamp : 7/17/2008 6:16:59 PM

FullName : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

AppDomainName : /LM/W3SVC/1/Root/TestDev-2-128607922162285048

ThreadIdentity :

WindowsIdentity : XXX\IIS_SVC

 

Category: General

Priority: 0

EventId: 100

Severity: Error

Title:Services.ExceptionHandling

Machine: SQL1

Application Domain: /LM/W3SVC/1/Root/TestDev-2-128607922162285048

Process Id: 7424

Process Name: c:\windows\system32\inetsrv\w3wp.exe

Win32 Thread Id: 2900

Thread Name:

Extended Properties:

 

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

Any direction in regards to resolving this issue would be appriciated. 

Jul 17, 2008 at 9:30 PM

Hi,

You're supposed to use the FaultContractExceptionHandler only in the policy used by the exception shielding behavior. This handler is really a specialized replace handler that contains a fault; the exception shielding behavior will handle this exception, extract the fault and return a FaultException<T> for it (where T is the runtime type of the fault).

I would assume you want to see the original exception logged instead of the FaultContractWrapperException. To do it just let the fault contract exception handler in the wcf exception shielding policy take care of mapping the original exception to a fault. And since you've only configured the fault contract handler in the sql exception's policy you can get rid of it (unless of course you plan on doing something else there).

I see you're using different fault contract types in the two instances of the fault contract handler in the different policies. If you need this behavior, just add both handlers in the main wcf shielding policy mapping them to different exception types; the handler associated to the most specific exception that matches would be used. Essentially, you would merge both your current policies into a single policy (the WCF shielding one).

Hope this helps,

Fernando

 

 

Jul 17, 2008 at 10:02 PM

Hi Fernando,

Thank you for educating me on the use of " FaultContractExceptionHandler"....

The reason I want to have two policies is that..

1. I want to handle exceptions as far as possible and I want Exception shielding to kick in only in case where I did not handle errors( I could predict or missed out handling) [ is it good the way I am seeing it or is it better to leave it to exception shielding??]
2. I don't want to log app errors ( ex: if you get some error response from database.. like item already exists etc) [ I guess I can achieve this even in exception shielding by adding new exception type and just adding  FaultContractExceptionhandler to it)

I am trying to use "FaultErrorMessageWithCode"( Fault contract defined) in both the policies.

I even tried Replace handler to replace the database exception with Fault... I could not get it work ( obvious.... right???)

I would appreciate if you could give your opinion on leaving exceptions to exception shielding vs handing each exception in catch block...



fsimonazzi wrote:

Hi,

You're supposed to use the FaultContractExceptionHandler only in the policy used by the exception shielding behavior. This handler is really a specialized replace handler that contains a fault; the exception shielding behavior will handle this exception, extract the fault and return a FaultException<T> for it (where T is the runtime type of the fault).

I would assume you want to see the original exception logged instead of the FaultContractWrapperException. To do it just let the fault contract exception handler in the wcf exception shielding policy take care of mapping the original exception to a fault. And since you've only configured the fault contract handler in the sql exception's policy you can get rid of it (unless of course you plan on doing something else there).

I see you're using different fault contract types in the two instances of the fault contract handler in the different policies. If you need this behavior, just add both handlers in the main wcf shielding policy mapping them to different exception types; the handler associated to the most specific exception that matches would be used. Essentially, you would merge both your current policies into a single policy (the WCF shielding one).

Hope this helps,

Fernando

 

 




Jul 17, 2008 at 10:27 PM

Hi,

About #1 I think I see your point about early handling, but I don't see an advantage in mapping to a fault contract before the exception shielding behavior gets a chance to do it unless you want to do it manually to control all the details.

As for #2, yes you can add exception types to the shielding policy to perform different actions for different exceptions. Unfortunately you cannot reuse handlers, so even if you want a slightly different processing for an exception (eg avoid logging) then you need to duplicate the common handlers.

I don't understand what didn't work about the replace handler, but in any case you wouldn't be able to provide a fault for a new fault exception if you followed this approach rendering this approach less useful.

Keep in mind that fault exceptions really make sense when thrown by a service operation. The shielding behavior lets you use a declarative approach to map your internal exceptions to faults for a fault exception, but you're free to throw your FaultExceptions internally if you wish. I guess it depends on how much of the kind of flexibility the declarative approach provides you need.

Regards,
Fernando


msaivara wrote:

Hi Fernando,

Thank you for educating me on the use of " FaultContractExceptionHandler"....

The reason I want to have two policies is that..

1. I want to handle exceptions as far as possible and I want Exception shielding to kick in only in case where I did not handle errors( I could predict or missed out handling) [ is it good the way I am seeing it or is it better to leave it to exception shielding??]
2. I don't want to log app errors ( ex: if you get some error response from database.. like item already exists etc) [ I guess I can achieve this even in exception shielding by adding new exception type and just adding  FaultContractExceptionhandler to it)

I am trying to use "FaultErrorMessageWithCode"( Fault contract defined) in both the policies.

I even tried Replace handler to replace the database exception with Fault... I could not get it work ( obvious.... right???)

I would appreciate if you could give your opinion on leaving exceptions to exception shielding vs handing each exception in catch block...



fsimonazzi wrote:

Hi,

You're supposed to use the FaultContractExceptionHandler only in the policy used by the exception shielding behavior. This handler is really a specialized replace handler that contains a fault; the exception shielding behavior will handle this exception, extract the fault and return a FaultException<T> for it (where T is the runtime type of the fault).

I would assume you want to see the original exception logged instead of the FaultContractWrapperException. To do it just let the fault contract exception handler in the wcf exception shielding policy take care of mapping the original exception to a fault. And since you've only configured the fault contract handler in the sql exception's policy you can get rid of it (unless of course you plan on doing something else there).

I see you're using different fault contract types in the two instances of the fault contract handler in the different policies. If you need this behavior, just add both handlers in the main wcf shielding policy mapping them to different exception types; the handler associated to the most specific exception that matches would be used. Essentially, you would merge both your current policies into a single policy (the WCF shielding one).

Hope this helps,

Fernando