How to override DataPortalException (or is there a better way to do what we need)

How to override DataPortalException (or is there a better way to do what we need)

Old forum URL: forums.lhotka.net/forums/t/12806.aspx


SethSpearman posted on Thursday, December 11, 2014

Hello,

Our shop makes extensive use of CSLA.  We have written asp.net mvc, winforms, web services, etc all using CSLA.

One of the things that we are really struggling with is how to get back useful debugging information when an error occurs.  The thing that makes it complicated is that our a single application can pass through multiple application server "layers" to do what it needs.

For example, (and this is a real example), we have a winforms application that makes a call to a remote data portal.  Sometimes (ordering related), the data portal makes a call to a webservice on another machine.  The webservice makes another remote data portal call to a server inside our firewall. 

We have another scenario which is similar but in this case the UI is an asp.net mvc application and it hops to a diferent web service (REST based) but it calls the same final data portal as the above example.

My "holy grail" would be to get back object state and stacktrace information for ALL of the hops and log into a database somewhere.  The user  would just see a GUID or something that says (call tech support with this number) and we would be able to look it up and the log  would be have all of the information across all hops.

Right now we have to fire up a bunch of Visual Studio environments and point the data portal to production data to replicate the issues. 

I was thinking if we could override DataPortalException and add a GUID and then use implement IDataPortalExceptionInspector and change all of our configurations to call a custom exception that it would be the beginning of solving our problem.  But I am not able to get something like that to work so far (because the client side DataPortalException does not know how to deserialize the GUID property of the new exception type).  That was one of many errors I have encountered to try to get this to work.

Is there an easier way to do it?  Or am I on the right track?  I am not an engineer/architect so if you could give me an overview of the best solution that would be great.

We are testing this on the VERY NEWEST version of CSLA (4.5.601)  and .net 4.5.

Seth

 

 

skagen00 replied on Friday, December 12, 2014

We use the enterprise library for exception logging, and here's what we end up doing.

On our base objects (the layer right on BusinessBase<T> for example), we do a try/catch within the DP_Fetch, DP_Create, etc.

        /// <summary>
        /// Retrieves an existing business object.
        /// </summary>
        /// <param name="criteria">
        /// An <see cref="Object"/> containing information necessary for retrieval.
        /// </param>
        protected virtual void DataPortal_Fetch(object criteria)
        {
            try
            {
                // Add the criteria to the debug objects collection.
                OurProductLocalContext.AddDebugObject(criteria);

                using (var dalFactory = DalFactory.GetManager())
                {
                    var dal = dalFactory.GetProvider<TData>(typeof(T));
                    TData data = dal.Fetch(criteria);
                    if (data != null) FetchCore(data);
                }
            }
            catch (Exception e)
            {
                OurProductEnterpriseLibraryUtility.HandleException(e, OurProductExceptionPolicy.ReleaseStandardPolicy);
            }
        }

We also add the current object during the dataportal invocation to this "context" object.

        protected override void DataPortal_OnDataPortalInvoke(DataPortalEventArgs e)
        {
            OurProductLocalContext.AddDebugObject(this); // Add the current object to the debug objects collection

            base.DataPortal_OnDataPortalInvoke(e);
        }

This context object happens to live in Csla.ApplicationContext.LocalContext.

We have a database trace listener attached, which ends up logging a nice XML representation of the objects to the database - because we have all the objects we care about in the LocalContext, we can iterate over them and write them out.

Truthfully, it haven't been used as much as I thought it would have been when I created it, but it does successfully give you the state of the objects at the time of the error.

It can be very verbose for certain objects, so it does require some maintenance.

Attached some of the key methods I use to write out a collection of objects to XML...

SethSpearman replied on Friday, December 12, 2014

skagen,

Thanks for your reply.  It has given me some things to try. 

One difference between your suggestion and what I was thinking how it would be done is that your  are actually doing the logging on the server side. 

One nice about doing things on the server side is that I have a reference to the BusinessObject property.  I have noticed that on the client side the DataPortalException.BusinessObject is always null.  The documentation seems to indicate that the BusinessObject property should contain the business object at the time of the exception. 

But, again, for me it is null.  Do you know why it might be null.  Or is that why you are doing the work on the server side?

One other thing...is the reason you use the Enterprise Library ... does it automatically serialize the object into a format that can be persisted (like xml...per your post).  I am struggling with how to persist the exception details.

Seth

skagen00 replied on Friday, December 12, 2014

Ah - sorry I guess the type of application matters a bit now doesn't it, along with what the desires are for logging.  Mine is for a Silverlight application and the logging I presented is just for the DP calls that happen against the server.

For logging client side there is definitely less contextual information.  Could have a ton of stuff in memory and not necessarily clear what aspects in memory would be important for that particular exception.  We do log things back to the server by sending the exception object to be logged, but no business object information is logged.

 

SethSpearman replied on Friday, December 12, 2014

OK...thanks for your reply.  It was helpful.

Seth

Copyright (c) Marimer LLC