4 Replies Latest reply on Aug 2, 2011 6:28 AM by anthonycor21

    Listening for UncaughtErrorEvents from SubApp loaded by SWFLoader

    anthonycor21 Level 1

      I can't seem to get my uncaughtErrorEvents listener to fire when attached to the loader.uncaughtErrorEvents  or loaded content's loaderInfo.uncaughtErrorEvents when loading a swf via SWFLoader.

       

      I have a main Flex Application ('A.swf') loading a SubApplication  (defined in' B.swf') via a SWFLoader and I need to listen for  UncaughtErrorEvent from the SubApplication. I'm not able to get my event  listeners to be called when I throw an error from within the SubApp  ('B.swf').

       

      After reading the asDoc for UncaughtErrorEvent and  UncaughtErrorEvents It states that the UncaughtErrorEvent should go through the normal capture, target, and bubble phases through the loaderInfo hierarchy. This doesn't seem to be the case or I'm not understanding the documentation/usage.

       

      I have added an event listener to A.swf's loaderInfo  (The 'outter' main app) and also to B.swf's loaderInfo (though the Docs  say not to do it here it is part of the event sequence in the capture  and bubble phase...) as well as the SWFLoader internal  FlexLoader.uncaughtErrorEvent (per Docs) like so:

       

      SWFLoader's internal FlexLoader uncaughtErrorEvents

      swfLoader.content.loaderInfo.loader.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorFunction ); 

       

      and the loaded SWF's loaderInfo:

       

      swfLoader.content.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorFunction ); 

       

       

      When I throw an Error from the SubApplication (B.swf). Only the 'outter' main app's (A.swf) event listener gets called. Which you expect, at first, if it is in the capture phase, but it isn't in that eventPhase at all. When debugging the eventPhase is in the EventPhase.AT_TARGET phase while being handled by A.swf's LoaderInfo, howeever the ASDoc says the Target phase should be B.swf's LoaderInfo.

       

      Is this a bug between Flash player and Flex where the event isn't flowing correctly as stated in the ASDoc for UncaughtErrorEvent?

        • 1. Re: Listening for UncaughtErrorEvents from SubApp loaded by SWFLoader
          Flex harUI Adobe Employee

          It might be that the error is being thrown from a class that is also in

          A.swf?

           

          Post your simplified test case if that isn't ture.

          • 2. Re: Listening for UncaughtErrorEvents from SubApp loaded by SWFLoader
            anthonycor21 Level 1

            Thanks for the reply Alex.

             

            The Outer main swf and the SubApp swf are in different ApplicationDomains (sibilings to each other) so they should not be sharing the class that is throwing the error. I should note that these two Applications are purely based on MX components, this is important later on.

             

            I was originally throwing the error from a Button click handler from B.swf:

            <mx:Button label="Throw Error" click="callLater( throwUncaughtError )" />

             

            I was wrapping the handler function in a callLater because without it the error is not caught at all and the default flash dialog console just appears with the error. The A.swf's loaderInfo.uncaughtErrorEvents handler was not even firing unless I wrapped it a callLater.

             

            I realized that Flash Builder's default to link the 4.1 SDK library via Runtime shared libraries was what was causing the A.swf's loaderInfo.uncaughtErrorEvent to fire in the AT_TARGET phase when using callLater. This is because the UIComponent's callLater method queue structure is shared between the two SWFs and therefore inside a function executing off the method queue A.swf's loaderInfo IS the TARGET... explainable, but at first thought that isn't how I'd expect this to work.

             

             

            I then decided to test this out by setting the SDK library to merge into the code for both A.swf and B.swf and removing the  callLater. IT WORKS!  B.swf's (the SubApp) loaderInfo.uncaughtErrorEvents handler fires and I prevent the default (flash error console from appearing) and can stopImmediatePropagation so A.swf's loaderInfo.uncaughtErrorEvents handler doesn't fire.

             

            Perfect besides having to merge the SDK libraries into each swf independently.... size killer.

             

             

            In summary, using the same exact code for A.swf and B.swf:

             

            1. When the SDK libraries are RSL - no UncaughtErrorEvents, neither A.swf's or B.swf's, is called. Instead the default flash error console appears with no chance to handle the uncaught error.

             

            2. When the SDK libraries are Merged into the code - both A.swf's and B.swf's uncaughtErrorEvents  will be called, according to the asDoc documented sequence; B.swf's uncaughtErrorEvents in the AT_TARGET phase and A.swf's uncaughtErrorEvents in the BUBBLE phase.

             

            Moreover, if I build a pure Spark implementation everything works even when referencing the SDK libraries as RSL.

             

            Does this indicate a bug in the globalplayer (flash player code)'s logic for handling UncaughtErrorEvents listeners within the loaderInfo hierarchy when the Flex SDK is Shared code between the SWFs?

             

            OR

             

            Since it works in Spark, is it an issue with how the flex2.compiler.mxml.Compiler turns MX based mxml components into generated AS classes (it hooks up the inline event listeners of child UIComponentDescriptor using a generic object and the click function is specified as a STRING and has to use untyped bracket notation to lookup on the UICompoent when adding it as a listener:

             

            new mx.core.UIComponentDescriptor({
                          type: mx.controls.Button
                          ,
                          events: {
                            click: "___B_Button1_click"
                          }

                          ,
                          propertiesFactory: function():Object { return {
                            label: "Throw Error"
                          }}
                        })
                      ]
                    }}

             

             

            Where as Spark does this correctly and generates Factory functions for setting up child UIComponents when converting Spark component mxml to AS:

             

            private function _B_Button1_c() : spark.components.Button
            {
                var temp : spark.components.Button = new spark.components.Button();
                temp.label = "Throw Error";
               temp.addEventListener("click", ___B_Button1_click);
                if (!temp.document) temp.document = this;
                mx.binding.BindingManager.executeBindings(this, "temp", temp);
                return temp;
            }

             

            /**
            * @private
            **/
            public function ___B_Button1_click(event:flash.events.MouseEvent):void
            {
                throwUncaughtError()
            }

             

             

            Sadly, moving to pure Spark would be a big hit is my project's schedule and at this point and likely isn't feasible. I have examples (with view source) built in MX for both the RSL and MERGE cases, I just don't know how to attach them here.

             

            Sorry for the long comments and thanks again!

            • 3. Re: Listening for UncaughtErrorEvents from SubApp loaded by SWFLoader
              Flex harUI Adobe Employee

              Spark apps work with RSLs but MX apps don't?  Please file a bug with a small

              test case so we can investigate.