PDA

View Full Version : [CLOSED] Info/Suggestion on ExtJS listener exception management and client page/event lifetyme



adrianot
Feb 26, 2014, 2:02 PM
Hello,

I am experiencing the following behavior of the listeners, and I would like to understand better if we're doing it wrong or if this is by "design".

See the attached script.

Let's assume the following:
- we have a complex page that dynamically loads different parts through AJAX (modules) PartialViewResults,
- suppose we would like to track the "added" event of the container itself (a subclasses Panel).
- the function attached on the "added" listener breaks for some unhandled exception

I verified that the behavior on the page is absolutely unexpected. The complete page composition is broken (nothing is displayed).

It seems that firing listeners, when exceptions aren't managed with a try/catch block... it breaks the entire rendering/layout logic...

Is there any workaround apart adding a try/catch to any listener implementation? I am concerned about breaking an entire portal when a single module throws an exception in one of its handlers.

Thank you!

geoffrey.mcgill
Feb 26, 2014, 7:36 PM
Hi,

Any chance you could simplify this scenario down to a sample that reproduces the issue? This would make it easier for us (at least me) to wrap our heads around the problem.

Daniil
Feb 27, 2014, 4:20 AM
Hi,

Yes, an uncaught JavaScript error breaks everything, it just stops the JavaScript engine.

There are two ways to catch JavaScript errors.

One of them you mentioned - "try catch" blocks. You can use it in your own JavaScript code.

Another way is a window.onerror. It should allow to catch the errors globally.
http://www.w3schools.com/tags/ref_eventattributes.asp

Returning true from an onerror handler means preventing a default browser action.

Example

<%@ Page Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<!DOCTYPE html>
<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body onerror="console.log(event); return true;">
<form runat="server">
<ext:ResourceManager runat="server" />

<ext:Button runat="server" Text="Throw error" Handler="notExistingFunction()" />
</form>
</body>
</html>


I am a bit unsure about supporting onerror in different browsers, but it probably should be fine.

adrianot
Feb 27, 2014, 7:52 AM
Hi Geoffrey/Daniil first of all thank you for your help :-)

I can show you some sample code that reproduce the behavior. The issue we're experiencing is strictly related to certain events (for instance "AfterRender") where the layout engine completely breaks. Note that we tried also the "Exception" listener to manage the error, the listener is fired correctly, but after that, any change to the layout (adding new components, resizing, etc... doesn't work).

View:



<ext:Viewport runat="server">
<Items>
<ext:Panel ID="ContainerPnl" ItemID="ContainerPnl" runat="server" Title="Container 1">
<Loader runat="server" Url="~/Portal/TestPartial" Mode="Script" AutoLoad="false">
<Params>
<ext:Parameter Name="containerId" Value="#{ContainerPnl}" />
</Params>
<Listeners>
<Exception Handler="console.error('Container 1 Loader error!');" />
</Listeners>
</Loader>
<Tools>
<ext:Tool Type="Gear">
<Listeners>
<Click Handler="#{ContainerPnl}.getLoader().load();" />
</Listeners>
</ext:Tool>
</Tools>
</ext:Panel>

<ext:Panel ID="ContainerPnl2" runat="server" Title="Container 2">
<Loader ID="Loader1" runat="server" Url="~/Portal/TestPartial2" Mode="Script" AutoLoad="false">
<Params>
<ext:Parameter Name="containerId" Value="#{ContainerPnl2}" />
</Params>
<Listeners>
<Exception Handler="console.error('Container 2 Loader error!');" />
</Listeners>
</Loader>
<Tools>
<ext:Tool Type="Gear">
<Listeners>
<Click Handler="#{ContainerPnl2}.getLoader().load();" />
</Listeners>
</ext:Tool>
</Tools>
</ext:Panel>

</Items>
</ext:Viewport>


Action:



Function TestPartial(containerId As String) As ActionResult
Return New PartialViewResult With {
.IDMode = Ext.Net.IDMode.Predictable,
.RenderMode = Ext.Net.RenderMode.AddTo,
.SingleControl = True,
.WrapByScriptTag = False,
.ContainerId = containerId,
.Namespace = "Portal"
}
End Function

Function TestPartial2(containerId As String) As ActionResult
Return New PartialViewResult With {
.IDMode = Ext.Net.IDMode.Predictable,
.RenderMode = Ext.Net.RenderMode.AddTo,
.SingleControl = True,
.WrapByScriptTag = False,
.ContainerId = containerId,
.Namespace = "Portal"
}
End Function


PartialView1:

<ext:Panel ID="PartialViewPanel" runat="server" Border="false" Title="Partial View Panel" Namespace="Portal">
<Content>
Test Partial Content
</Content>
<Listeners>
<BeforeAdd Handler="console.log('before add');" />
<Added Handler="console.log('added');" />
<BeforeRender Handler="console.log('before render');" />
<AfterRender Handler="undefinedFunction();" />
<Activate Handler="console.log('activate');" />
</Listeners>
</ext:Panel>


PartialView2:

<ext:Panel ID="PartialViewPanel" runat="server" Border="false" Title="Partial View Panel" Namespace="Portal">
<Content>
Test Partial Content 2
</Content>
<Listeners>
<BeforeAdd Handler="console.log('before add');" />
<Added Handler="console.log('added');" />
<BeforeRender Handler="console.log('before render');" />
<AfterRender Handler="console.log('after render');" />
<Activate Handler="console.log('activate');" />
</Listeners>
</ext:Panel>


In order to fix this we need to wrap the listener handler within a "try/catch" block manually.
Now I am asking whether this is a limitation of the Exception handler, or if this behavior is by design somehow?

Thank you again!

Daniil
Feb 27, 2014, 11:55 AM
Well, the Exception listener cannot catch a JavaScript error inside an AfterRender listener. At least, because it fires later.

Yes, wrapping the AfterRender code in a try-catch block or using a window's onerror might be a solution.

adrianot
Feb 27, 2014, 12:40 PM
Hi Daniil, it's fine for us, however do you think that wrapping a "standard" try/catch on the listeners could help avoiding this kind of breaks?

Basically I would like to avoid breaking other "modules" of my application without worrying about having to add manually a try/catch on every handler.

I am thinking about overriding somehow the "addEventListener" method so that it wraps the actual handler in a try/catch block... is it something feasible easily from your point of view? Obviously I need this only for listeners that break page composition, like "AfterRender" for instance.

What's your opinion? I've seen that "window.onError" event is available only on certain browsers (modern ones), and I need to make it compatible to ask many browser as I could.

Thank you for a suggestion and for the quick answers!
Keep up the great work!

Daniil
Feb 28, 2014, 2:57 AM
Hi Daniil, it's fine for us, however do you think that wrapping a "standard" try/catch on the listeners could help avoiding this kind of breaks?


Yes, I do.



I am thinking about overriding somehow the "addEventListener" method so that it wraps the actual handler in a try/catch block... is it something feasible easily from your point of view?


Well, it sounds interesting. You could try.


I've seen that "window.onError" event is available only on certain browsers (modern ones), and I need to make it compatible to ask many browser as I could.


Please clarify where did you see it? Seems it is supported in old browsers:
http://www.w3.org/wiki/DOM/window.onerror

But here I see that "try catch" might be not supported in old browsers.
http://programmers.stackexchange.com/questions/144326/try-catch-in-javascript-isnt-it-a-good-practice

You also might be interested to read these discussions:
http://stackoverflow.com/questions/5260526/use-of-try-catch-in-javascript
http://stackoverflow.com/questions/3217294/javascript-try-catch-performance-vs-error-checking-code
http://stackoverflow.com/questions/12609527/why-isnt-try-catch-used-more-often-in-javascript