DataPortalInvokeComplete Event Not Raised After Exception

DataPortalInvokeComplete Event Not Raised After Exception

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


Wally417 posted on Friday, January 11, 2008

I've noticed that the client-side DataPortalInvokeComplete event is not raised if a server-side DataPortalException is caught. The host application can know that a data portal operation is in progress but in the current situation cannot reliably know when the data portal operation is complete. I suggest putting the OnDataPortalInvokeComplete method calls in a finally block to ensure (as best as possible) that DataPortalInvoke/DataPortalInvokeComplete events always come in pairs.

Thanks for your consideration,

Mike

ajj3085 replied on Friday, January 11, 2008

I'm not sure I follow... you can use OnDataPortalException to find out if the operation "completed" in failure.  I think complete here means completed successfully.

Wally417 replied on Friday, January 11, 2008

I understand the OnDataPortalException method to be a server-side method. I'm looking at the client side. Here's a code excerpt from DataPortal.Fetch:

OnDataPortalInvoke(new DataPortalEventArgs(dpContext));

try

{

    result = proxy.Fetch(objectType, criteria, dpContext);

}

catch (Server.DataPortalException ex)

{

    result = ex.Result;

    if (proxy.IsServerRemote)

        ApplicationContext.SetGlobalContext(result.GlobalContext);

// some code cut here for brevity

    throw new DataPortalException(String.Format("DataPortal.Fetch {0} ({1})", Resources.Failed, innerMessage),

        ex.InnerException, result.ReturnObject);

}

if (proxy.IsServerRemote)

    ApplicationContext.SetGlobalContext(result.GlobalContext);

OnDataPortalInvokeComplete(new DataPortalEventArgs(dpContext));

Notice that on the client side no OnDataPortalInvokeComplete method is called if a DataPortalException occurs. I suggest the following code has the same semantics except a DataPortalInvokeComplete event is raised on the client side regardless of whether or not there was an exception on the server side:

OnDataPortalInvoke(new DataPortalEventArgs(dpContext));

try

{

    result = proxy.Fetch(objectType, criteria, dpContext);

}

catch (Server.DataPortalException ex)

{

    result = ex.Result;

    throw new DataPortalException(String.Format("DataPortal.Fetch {0} ({1})",  Resources.Failed,   ex.InnerException.InnerException),

    ex.InnerException, result.ReturnObject);

}

finally

{

    if (proxy.IsServerRemote)

        ApplicationContext.SetGlobalContext(result.GlobalContext);

    OnDataPortalInvokeComplete(new DataPortalEventArgs(dpContext));

}

Can the same net result be obtained some other way on the client side? Is there a downside to this change other than the behavior changing?

 

Thanks,

Mike

RockfordLhotka replied on Friday, January 11, 2008

Yes, that's an interesting point.

I wonder if there shouldn't be a client-side exception event for parity with the server-side behavior?

Wally417 replied on Friday, January 11, 2008

I suppose you could raise an event on the client side, but we already get a DataPortalException thrown. That is certainly sufficient for my needs. Others may ahve a use for it.

I do suggest changing the client DataPortal code as above or in a way that provides the same effect: a DataPortalInvokeComplete event is raised whether a server-side exception was encountered or not.

Thank you!

Mike

RockfordLhotka replied on Saturday, January 12, 2008

The reason I don’t raise the Complete event is because the operation didn’t complete due to an exception. I’m not sure it makes logical sense to raise a Complete event for something that didn’t complete.

 

What is the specific thing you are trying to accomplish?

 

Rocky

 

 

From: Wally417 [mailto:cslanet@lhotka.net]
Sent: Friday, January 11, 2008 9:21 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] DataPortalInvokeComplete Event Not Raised After Exception

 

I suppose you could raise an event on the client side, but we already get a DataPortalException thrown. That is certainly sufficient for my needs. Others may ahve a use for it.

I do suggest changing the client DataPortal code as above or in a way that provides the same effect: a DataPortalInvokeComplete event is raised whether a server-side exception was encountered or not.

Thank you!

Mike



Wally417 replied on Saturday, January 12, 2008

Right now I'd like to do some simple UI animation while a DataPortal event is taking place. I can easily imagine other ways in which I might want to use those events, including instrumentation (as in your post here http://forums.lhotka.net/forums/post/2409.aspx) or DataPortal metering. The DataPortalInvoke/DataPortalInvokeComplete events seem to me the natural hooks for this kind of functionality. The alternative that jumps into my mind is to sprinkle DataPortalInvoke/Complete analogs in the business class DataPortal_xxx methods, which I think is not a particularly palatble solution.

You could add a boolean Success flag to DataPortalEventArgs to indicate whether the operation completed successfully or with an exception.

I suppose you may consider making my suggested modifications a breaking change since the behavior of the framework would indeed be different. I suspect this would be a very mild severity breaking change, though. A scan of the forum posts for DataPortalInvoke/Complete/DataPortalEventArgs leads me to think users of these events assume that if a DataPortalInvoke event is raised, a DataPortalInvokeComplete event will follow.

If I use the current framework code and instrument an application to gather DataPortal method timings using the Invoke/Complete events as you suggest in the post noted above, how would I handle the timer in the case of an exception? Would I need to add code to each DataPortalException catch block to signal completion of the method call? 

Thanks again!

Mike

RockfordLhotka replied on Saturday, January 12, 2008

If I added a DataPortalException event it would be a static/Shared event just like the current events, so I imagine you’d call your timer-end code from both the Complete and Exception events – but there’d be just two locations, not n locations.

 

However, your idea of passing a status field (and the exception itself perhaps) to the Completed event seems quite reasonable as well. I don’t remember if those events receive any args parameter at the moment, but they’d need to start doing so to follow this train of thought. That’d be a breaking change if such a parameter needs to be added (at least in C# - VB 9 now has relaxed delegate invocation that would allow any existing event handler to work).

 

Rocky

 

 

From: Wally417 [mailto:cslanet@lhotka.net]
Sent: Saturday, January 12, 2008 4:45 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: DataPortalInvokeComplete Event Not Raised After Exception

 

Right now I'd like to do some simple UI animation while a DataPortal event is taking place. I can easily imagine other ways in which I might want to use those events, including instrumentation (as in your post here http://forums.lhotka.net/forums/post/2409.aspx) or DataPortal metering. The DataPortalInvoke/DataPortalInvokeComplete events seem to me the natural hooks for this kind of functionality. The alternative that jumps into my mind is to sprinkle DataPortalInvoke/Complete analogs in the business class DataPortal_xxx methods, which I think is not a particularly palatble solution.

You could add a boolean Success flag to DataPortalEventArgs to indicate whether the operation completed successfully or with an exception.

I suppose you may consider making my suggested modifications a breaking change since the behavior of the framework would indeed be different. I suspect this would be a very mild severity breaking change, though. A scan of the forum posts for DataPortalInvoke/Complete/DataPortalEventArgs leads me to think users of these events assume that if a DataPortalInvoke event is raised, a DataPortalInvokeComplete event will follow.

If I use the current framework code and instrument an application to gather DataPortal method timings using the Invoke/Complete events as you suggest in the post noted above, how would I handle the timer in the case of an exception? Would I need to add code to each DataPortalException catch block to signal completion of the method call? 

Thanks again!

Mike



Wally417 replied on Saturday, January 12, 2008

OnDataPortalInvokeComplete takes a DataPortalEventArgs parameter, so it sounds like a deal!Smile [:)] 

(OK, I understand it takes more thought than that. There may be very good reason to leave the behavior just as it is.)

Mike

Copyright (c) Marimer LLC