[Event System] Combining Server Side NotifyWidget with InvokeEventHandlers generates an error

[Event System] Combining Server Side NotifyWidget with InvokeEventHandlers generates an error

  
Forge Component
(19)
Published on 1 Nov by Leonardo Fernandes
19 votes
Published on 1 Nov by Leonardo Fernandes
Hello Leonardo,

We are using the EventSystem component in platform server 8 (v8.0.1.35) and we are using the version 1.4 of this component (Latest available for 8).
It's all working fine and performant, but today i came across an error that implies to dig deep in the component, but since it's closed i cannot investigate the cause of the problem.

I have a web block inside a ListRecords, and when i trigger the NotifyWidget Server Side, and then invoke an event handler, the application throws the following error:
Object reference not set to an instance of an object.
   at OutSystems.HubEdition.WebWidgets.Iterator.OnBubbleEvent(Object sender, EventArgs args)
   at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
   at System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e)
   at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
   at OutSystems.HubEdition.WebWidgets.Button.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

I manage to replicate the problem in a simple eSpace (attachement).
Can you please run the eSpace to see if there is something wrong with the usage of the component or if it is a limitation of the component itself?

Thanks, Nuno Guedes.
Hello Leonardo,

I just saw that you released a new version of this component for 8.0 (8.2.0), and thank you very much for that, i try to publish it and refreshed the eSpace of the above post, but the error still remains.

Thanks.
Nuno Guedes
Hi Nuno. I can confirm that the error persists.
I took a quick look, and it seems to be caused by two circumstances coupled together:
1. The button clicked is inside a web block, inside of a list records.
2. Inside the request, the list records is refreshed, throwing away all the web blocks, and replacing by newer web blocks.

It seems that something is misbehaving in the end of the request, but I will have to dig really deep to track it down. Is this a blocking issue for you?

As a workaround, I would suggest you to replace the server-side notify by a client-side one.
Hello Leonardo,

Thaks for your quick reply,i already did what you sugested and it's working fine, so, it is not a blocking issue for me. However, i decided to share this issue in the community so that the problem could be fixed in the future, because it  would be very nice to take advantage of the full server side event system.

Thanks. Nuno Guedes
Sure, and thank you for that!
I will look into it in the short term.
Hello Nuno. This issue that you were experiencing is fixed in the newer versions. Try it out and get back to me if you find any problems!
Hello Leonardo,

I tested the new version, and i confirm that it works for the case described above, but unfortunately i ran into another problem, this time i have two nested List Records, and when i trigger notify widget, throws the same error.
There is an eSpace in attatch, if you can, please try the screen NestedListRecords to replicate the error, i am using Platform Server 8.0.1.35.

Thanks,
Nuno Guedes
Hi Nuno.
The problem in your test case appears to be related to the button inside the web block being a submit kind of button. If you change the button method to ajax, it will work.

Now, I would like to understand if you really need a submit button in your application, or you simply left the default method.
Hello Leonardo,

I dont have the need for a submit button, this was just an example, what i really needed in my application was to trigger notifywidget from a nested block right from the preparation.

There is an example in attach.

Thanks,
Nuno Guedes.
I see... that problem is different from the others.

I will have a look at it. Thanks,
Leonardo Fernandes
Well, Nuno, can you try your use case with the latest component version (8.4.1)?

Thanks.
Hello Leonardo,

I tried the latest version (8.4.2) and i confirm that all use cases discussed in this topic are working fine.

Thanks,
Nuno Guedes.
Hello Leonardo,

We have recently upgrade to the latest version of this component in our work infrastructure, and we came across an error in a situation that previously worked:

We have a sumbit button that calls an event that has an ajax refresh in it, this is because this event action is used by a combo box (and ajax is the only option), but we must ensure that this logic is executed before we save the data, so we used the Invoke action to reuse the screen action.

With the latest version, it throws the error below.
You can replicate the error by clicking the button "Invoke Event Submit" of the eSpace in attatch.

Thanks.
Nuno Guedes

Server Error in '/EventSystemTest' Application.


Server cannot set status after HTTP headers have been sent.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Web.HttpException: Server cannot set status after HTTP headers have been sent.
Hi Nuno. Yes, I was aware of this error, however it only happens if you mix an ajax refresh node with a submit button (or link).

The standard platform behavior is that the ajax refresh nodes are ignored during a submit request. However, when using a event handler (or even a server-side notify), the control passes through the OnNotify action of the web block, which is considered an ajax call. This confuses the platform, and enables the ajax refresh nodes, even though the original button (or link) had a submit method.

Is it possible for you to use ajax submit on the offending button (or link)? That would be an easy workaround, however it could change slightly your logic.

I will need some time to see if I can solve this problem, because it depends on the internals of the ajax refresh of the platform...

Best regards,
Leonardo Fernandes
Hello Leonardo,

We changed the submit button to ajax button and it worked fine, and for thar reason, this issue is not a blocking issue right now, i just reported the situation because it didn't occur with previeous versions of the component, and could be caused by something missed out in this version. Now i know that is not a simple scenario to fix, but we are sure that you will manage to work it out :)

Cheers,
Nuno Guedes
Hello Nuno. I'm happy to say that the last issue that you reported (Server cannot set status after HTTP headers have been sent) is fixed in the latest version.
Hello Leonardo,

I tested the latest version and i can confirm that it works perfectly now, thanks a lot.

Cheers
Nuno Guedes
Hello Leonardo,

While using the component, the user has experienced a rare situation that generated a application issue.
We have a block with a table records inside it, this table records has a delete button.
What happend was that we were deleting a record and were refreshing the table records before the InvokeNotifyWidget was called, and this generated the following error:

 

Cannot find widget wtlrInt$ctl00$wt11$wttrIntegers$ctl04$wt4
   at ssEventSystemTest.RssExtensionEventSystem.MssTriggerNotifyWidget(HeContext heContext, String inParamWebBlockRuntimeWidgetId, String inParamMessage)
   at ssEventSystemTest.Flows.FlowWebFlow1.WBlkWebBlock.CommandTriggerNotifyWidget2(HeContext heContext)
   at ssEventSystemTest.Flows.FlowWebFlow1.WBlkWebBlock.wt4_Click(Object sender, EventArgs e)
Exception has been thrown by the target of an invocation.
   at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
   at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at ssEventSystemTest.Flows.FlowWebFlow1.WBlkWebBlock.recTabletrIntegers_Select(Object sender, DataGridCommandEventArgs e)
   at System.Web.UI.WebControls.DataGrid.OnItemCommand(DataGridCommandEventArgs e)
   at System.Web.UI.WebControls.DataGrid.OnBubbleEvent(Object source, EventArgs e)
   at OutSystems.HubEdition.WebWidgets.OSDataGrid.OnBubbleEvent(Object source, EventArgs e)
   at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
   at System.Web.UI.WebControls.DataGridItem.OnBubbleEvent(Object source, EventArgs e)
   at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
   at System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e)
   at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
   at OutSystems.HubEdition.WebWidgets.Button.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

This situation had a simple workaround that consisted in making the refresh of the table records after the InvokeNotifyWidget action, but since the error that is thrown by the application is not intuitive, we took sevral hours to figure out a solution to this problem, that's why i'm letting you know about it.
The eSpace in attach can help you replicate the error, can you see if it's possible to fix this issue?

Thanks.
Nuno Guedes.

Hi Nuno. I'm glad that you've found a workaround.

I will have a look at it pretty soon, and I'll let you know of my findings. Thanks.
Leonardo Fernandes
Hello Nuno.
Latest version (8.4.5 / 9.4.5) fixes the last error that you have reported. Thank you!
Ah, Nuno. I noticed that you use the TriggerNotifyWidget action directly from the EventSystem extension. It works, but you could also use the InvokeNotifyWidget from the events eSpace (not the extension...).

Besides being easier to find (now everything is available from the eSpace), the action from the eSpace allows you to provide arguments to the notify action (using the API described on lesson 06).
Hello Leonardo,

I've tested and i can confirm that it works fine now, thank you very much.

As for using the InvokeNotifyWidget direcly from the extension,i already noticed that this action is also available in the eSpace, and in all my company projects i am ising it from the eSpace because is also much better to consume all features from the component only through one eSpace.
As for the example eSpace, since is just a sample that i use to replicate eventual errors, i haven't change that part because it didn't felt relevant for the error replication.

Cheers,
Nuno Guedes