Exception Handling + Logging w/ Extended Properties + Fault Contract Exception Handler

Topics: Exception Handling Application Block, Logging Application Block
Nov 8, 2010 at 8:11 PM

Well - the discussion title says it all.

I'm trying to:
Use Exception Handling Block
Add 2 extended properties
Log the exception + the extended properties to the Logging database
Then wrap it all up in a WCF Fault (using Exception Shielding) & send it back to my Silverlight client.

What is the best approach for this?

Thanks in advanced for the help on this.

Nov 8, 2010 at 11:31 PM

The out of the box database trace listener logs the extended properties as part of the FormattedMessage column of the Log table.  Do you want to log the extended properties on a different column?  If yes, then the easiest way to do this would be to modify the WriteLog stored procedure to extract the extended properties from the @FormattedMessage parameter.  Another option would be to create a custom database trace listener for this which would contain that logic.

As for wrapping the exception, just make sure to add the extended properties in the .Data property of the exception thrown in the WCF service.  Provide a fault contract which contains all the properties you want to be mapped with the exception and specify the mappings in the Fault Contract Exception handler.

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

Nov 9, 2010 at 1:52 PM

Thanks Sarah.

Actually - Yes we'd like to place the 2 extended properties into their own individual columns.  Can we add those new columns to the Log table in the Logging database?  And - the best way to do that is to do the string parse in the WriteLog stored procedure?

Also - I setup 2 policies - 1 to actually log the exception & the one for the exception shielding & it seems to work.  Is this the preferred method?

Thanks for all the help.

Nov 9, 2010 at 8:33 PM

Few more questions:

1.  What are all the properties available via the Fault Mappings?

I know of - {Guid}, {Message}, {Data}

2.  Is there a way to log the exception into the Logging database & then return the EventId in the Fault?

3.  Is there a way to log the exception into the Logging database & then return the HandlingInstanceId into the Fault?  I assume this is the {Guid} mapping?

Sorry for so many questions. Thanks again.

Nov 10, 2010 at 12:14 AM

"Can we add those new columns to the Log table in the Logging database?  And - the best way to do that is to do the string parse in the WriteLog stored procedure?"

Yes, you can add those new columns.  However, I'm not saying the best way is to parse the @FormattedMessage  parameter, that's just the easiest.  That approach would fail should someone modify the Template of your formatter to exclude the Extended Properties.  On the approach of using a custom trace listener, there wouldn't be any parsing logic in the stored procedure.  What I could think of is the additional parameters you want can be added in the Attributes collection of the custom trace listener and it would then contain the logic that will add those parameters when executing the stored procedure.   But in both approach, if you need to add new columns, you would also modify the stored procedure.   So that depends on you on where you are comfortable placing your logic, in the sp or in the custom trace listener.

"Also - I setup 2 policies - 1 to actually log the exception & the one for the exception shielding & it seems to work.  Is this the preferred method?"

You could combine it actually in one policy.

"What are all the properties available via the Fault Mappings?"

All properties of the originally exception.  The only extra information that is not really a property of the exception is the handling instance id {Guid}.

"Is there a way to log the exception into the Logging database & then return the EventId in the Fault?"

Returning the EventId in the fault is not directly supported.  A way I could think to do this is create your own LoggingExceptionHandler which adds the eventId in the .Data property of the exception being handled.  Why do you need the EventId in the fault anyway?

"Is there a way to log the exception into the Logging database & then return the HandlingInstanceId into the Fault?  I assume this is the {Guid} mapping?"

Yes, using the the {Guid} accomplishes that task.

 

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

Nov 10, 2010 at 2:25 PM

Ideally - I would like the Silverlight client to see the following information when a Server exception occurs:

1.  FriendlyMessage
2.  Original Exception Type
3.  Original Exception Source - (maybe - could be too much information)
4.  Original Exception Message
5.  HandlingInstanceId
6.  EventId - (right now unnecessary, but would be nice)

Then - when a Client Exception occurs I would like to:
1.  Log the Exception (Message, Type, Source, InnerException, & Stack Trace) on the Server
2.  Display the same information as above.

Sorry for all the questions.  Obviously - I'm pretty new at EntLib.

Let me know what it would take to accomplish this.

Nov 10, 2010 at 2:54 PM
Edited Nov 10, 2010 at 2:55 PM

OK - on this:

 

Here's my Service class (NOTE:  I'm throwing a SQL Exception inside the AuditInsert):

 

    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ExceptionShielding("Server Policy")]
    public class Audit
    {
        [OperationContract]
        [FaultContract(typeof(ServerFault))]
        public void InsertAuditRecord(AuditEvent evt)
        {
            AuditEventDataAccess eida = new AuditEventDataAccess();
            try
            {
                eida.Insert(evt);
            }
            catch (Exception ex)
            {
                Logger.HandleException(ex);
            }
        }
}

 

The Logger.HandleException is just:

            if (ex != null)
            {
                //Resolve an Exception Manager instance 
                var exManager = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>();
   
                    //add extended properties
                    ex.Data.Clear();
                    ex.Data.Add("UsrId", ClaimsIdentity.GetInstance().UserId);

                    rethrow = exManager.HandleException(ex, policy);
             }

 

My Server Policy is:
Server Policy --> SqlException --> Logging Exception Handler & Fault Contract Exception Handler

AND           ---> AllExceptions --> Logging Exception Handler

However - what happens is the Exception is logged in the Logging Database (which is great), BUT - then then the Fault is logged into the Database.  Is there anyway to avoid this?

Thanks again.

Nov 11, 2010 at 3:23 AM

Remove the try catch block code in your service  and that includes the call to exManager.HandleException.  You need not do this as exceptions are automatically being handled as long as you put the ExceptionShielding attribute in your service contract.

 

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

Jan 19, 2011 at 12:29 PM

How is it that using exception shielding, the error is reported back to the silverlight client, while in other cases, it is required to create a silverlightfaultbehavior extension, explicitly. Thanks in advance for the help.

Jan 20, 2011 at 10:00 AM

Sorry, I'm afraid I'm missing your question here. Maybe because I'm not really familiar with silverlightfaultbehavior extension. Anyway can you provide more information regarding your inquiry.

Also, we really appreciate starting a new discussion if it's a different topic, this is also to help others if they are looking for something or anything related with their problem/inquiry. Thanks.

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

Jan 20, 2011 at 10:13 AM

Thanks. Actually , in Silverlight and with using WCF, the error is not reported to the client normally. Its required to create a custom handler as pointed out by MS : http://msdn.microsoft.com/en-us/library/dd470096(VS.96).aspx.  This handler enables the fault to propogate to silverlight client.  However, as I learn more on this, with the exceptionshielding , EntLib, as used in the WCF, the fault is indeed propogated to the client and as also the core subject of this disc topic. I checked using the exception shielding , on services and the fault was propogated.  Keen to know more on this behavior...We also checked using the normal fault handling (without Entlib), the fault was not propogated.

Jan 21, 2011 at 2:52 AM
Edited Jan 21, 2011 at 3:44 AM

The way I see it is that the basic idea behind the exception shielding feature of EntLib and the SilverlightFaultBehavior extension is actually the same.  Since WCF is a SOAP-based application, processing information such as an exception needs to be converted in a SOAP fault message.  And that's what both essentially does, they convert the exception which occurred to a fault message.  EntLib's Exception Handling Application Block is there so you won't have to build your own behavior extension for such scenarios

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Jan 24, 2011 at 4:52 PM

Hi Sarah,

I as well, would like to add new columns to the logging database and the WriteLog SPROC. The approach that you mentioned above: "the additional parameters you want can be added in the Attributes collection of the custom trace listener and it would then contain the logic that will add those parameters when executing the stored procedure." I don't see an attributes collection in my custom trace listener of the web.config.

How would I go about doing this? By using the Enterprise Library Configuration Tool? If so, would this be under the "Template" setting? Or would the best approach be to modify the web.config directly?

Jan 25, 2011 at 10:10 AM

Check this thread http://entlib.codeplex.com/Thread/View.aspx?ThreadId=16196 see if it may help. You need to use the Enterprise Library Config Tool to add a Custom Trace Listener. Then in the Attribute Collection Property is found in your CustomTraceListener after succesfully adding it in your Logging configuration. It is a Key Value pair you just need to manually add. Hope this helps.

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

 

Jan 25, 2011 at 10:15 AM

Thanks Sarah...In fact the exception is reported by uisng the Exception SHielding part of the block. With normal fault handling using the exception block, same is not reported

Jan 26, 2011 at 5:23 AM

@sumit_joshi,

    Do you still have anything to clarify further relating to exception shielding?  Because if yes, I'm not sure if I was able to provide you the answer you needed in your previous post.  Did I? 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com