43

When I run a Flex application in the debug flash player I get an exception pop up as soon as something unexpected happened. However when a customer uses the application he does not use the debug flash player. In this case he does not get an exception pop up, but he UI is not working.

So for supportability reasons, I would like to catch any exception that can happen anywhere in the Flex UI and present an error message in a Flex internal popup. By using Java I would just encapsulate the whole UI code in a try/catch block, but with MXML applications in Flex I do not know, where I could perform such a general try/catch.

Yaba
  • 5,979
  • 8
  • 38
  • 44

9 Answers9

52

There is no way to be notified on uncaught exceptions in Flex 3. Adobe are aware of the problem but I don't know if they plan on creating a workaround.

The only solution as it stands is to put try/catch in logical places and make sure you are listening to the ERROR (or FAULT for webservices) event for anything that dispatches them.

Edit: Furthermore, it's actually impossible to catch an error thrown from an event handler. I have logged a bug on the Adobe Bug System.

Update 2010-01-12: Global error handling is now supported in Flash 10.1 and AIR 2.0 (both in beta), and is achieved by subscribing the UNCAUGHT_ERROR event of LoaderInfo.uncaughtErrorEvents. The following code is taken from the code sample on livedocs:

public class UncaughtErrorEventExample extends Sprite
{
    public function UncaughtErrorEventExample()
    {
        loaderInfo.uncaughtErrorEvents.addEventListener(
            UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
    }

    private function uncaughtErrorHandler(event:UncaughtErrorEvent):void
    {
        if (event.error is Error)
        {
            var error:Error = event.error as Error;
            // do something with the error
        }
        else if (event.error is ErrorEvent)
        {
            var errorEvent:ErrorEvent = event.error as ErrorEvent;
            // do something with the error
        }
        else
        {
            // a non-Error, non-ErrorEvent type was thrown and uncaught
        }
    }
Community
  • 1
  • 1
Richard Szalay
  • 83,269
  • 19
  • 178
  • 237
  • Does global error handling in Flash 10.1 require working with flex 3.5? 4? Or does it work in Flex 3 as well? – Assaf Lavie Mar 07 '10 at 14:54
  • 2
    My code above required Flex 4. However, it should work in any SDK running against 10.1 if you use `((IEventDispatcher)loaderInfo["uncaughtErrorEvents"]).addEventListener("uncaughtError", handlerFunction)`, because the properties will exist at runtime in the player. You could even wrap it with `if (loaderInfo.hasProperty("uncaughtErrorEvents") { }` to ensure it doesn't break in Flash 9/10 (the error handling won't work, of course, but it won't crash) – Richard Szalay Mar 07 '10 at 18:13
  • 1
    @Richard's comment: That would indeed by how you'd expect it to work, but unfortunately, it doesn't. If you compile with Flash Player 9 as target, and run it on Flash Player 10.1, loaderInfo["uncaughtErrorEvents"] is still not available! My interpretation: The Flash player, at runtime, looks at what player your swf was targetted to, and "hides" the features that weren't in that version yet. – Wouter Coekaerts Oct 20 '10 at 15:27
  • @Wouter - I also see that behavior. Feel free to vote/add comments to my bug: https://bugs.adobe.com/jira/browse/FB-27199 – Richard Szalay Oct 20 '10 at 22:27
  • 3
    To add to this answer: if you are running in a debug version of the Flash Player, the general runtime error dialog will still pop up. To prevent this, call event.preventDefault() inside your global error handler. – Christophe Herreman Oct 27 '10 at 12:36
  • @Wouter - It turns out the bug link I sent you is wrong. See this bug and the associated link: https://bugs.adobe.com/jira/browse/SDK-28018 – Richard Szalay Oct 27 '10 at 13:24
  • @Richard - thanks for pointing out that rsl issue! I've posted a workaround on SDK-28018. You might want to integrate that in your answer. – Wouter Coekaerts Oct 28 '10 at 15:53
  • If you add the verbose-stacktraces compiler option you'll get the stack trace for production swfs (the swf will be a bit larger though) – Clintm May 10 '16 at 16:59
9

There is a bug/feature request for this in the Adobe bug management system. Vote for it if it's important to you.

http://bugs.adobe.com/jira/browse/FP-444

4

It works in Flex 3.3.

 if(loaderInfo.hasOwnProperty("uncaughtErrorEvents")){
    IEventDispatcher(loaderInfo["uncaughtErrorEvents"]).addEventListener("uncaughtError", uncaughtErrorHandler);
 }
Termininja
  • 6,620
  • 12
  • 48
  • 49
3

Note that bug FP-444 (above) links to http://labs.adobe.com/technologies/flashplayer10/features.html#developer that since Oct 2009 shows that this will be possible as of 10.1, which currently, Oct 28, 2009 is still unreleased - so I guess we'll see if that is true when it gets released

Peter V. Mørch
  • 13,830
  • 8
  • 69
  • 103
3

Alternative to accepted answer, using try-catch. Slower, but more straightforward to read, I think.

try {
    loaderInfo.uncaughtErrorEvents.addEventListener("uncaughtError", onUncaughtError);
} catch (e:ReferenceError) {
    var spl:Array = Capabilities.version.split(" ");
    var verSpl:Array = spl[1].split(",");

    if (int(verSpl[0]) >= 10 &&
        int(verSpl[1]) >= 1) {
        // This version is 10.1 or greater - we should have been able to listen for uncaught errors...
        d.warn("Unable to listen for uncaught error events, despite flash version: " + Capabilities.version);
    }
}

Of course, you'll need to be using an up-to-date 10.1 playerglobal.swc in order to compile this code successfully: http://labs.adobe.com/downloads/flashplayer10.html

aaaidan
  • 7,093
  • 8
  • 66
  • 102
3

I'm using flex 4. I tried loaderInfo.UncaughtErrorEvents, but loaderInfo was not initialized so it gave me null reference error. Then i tried root.loaderInfo.UncaughtErrorEvents and the same story. I tried sprite.root.UncaughtErrorEvents, but there was no sprite object, I created one, but it didn't work. Finally I tried

systemManager.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR,globalUnCaughtErrorHandler.hanleUnCaughtError);

And guess what, it works like magic. check this

Rose
  • 2,792
  • 4
  • 28
  • 42
3

It works in Flex 3.5 and flash player 10:

  <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" addedToStage="application1_addedToStageHandler(event)">
    <mx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            
            protected function application1_addedToStageHandler(event:Event):void{              
                if(loaderInfo.hasOwnProperty("uncaughtErrorEvents")){
                    IEventDispatcher(loaderInfo["uncaughtErrorEvents"]).addEventListener("uncaughtError", uncaughtErrorHandler);
                }
                
                sdk.text = "Flex " + mx_internal::VERSION;
            }
            
            private function uncaughtErrorHandler(e:*):void{
                e.preventDefault();
                
                var s:String;

                if (e.error is Error)
                {
                    var error:Error = e.error as Error;
                    s = "Uncaught Error: " + error.errorID + ", " + error.name + ", " + error.message;
                }
                else
                {
                    var errorEvent:ErrorEvent = e.error as ErrorEvent;
                    s = "Uncaught ErrorEvent: " + errorEvent.text;
                }
                
                msg.text = s;
            }
            
            private function unCaught():void
            {
                var foo:String = null;
                trace(foo.length);
            }
        ]]>
    </mx:Script>
    <mx:VBox>
        <mx:Label id="sdk" fontSize="18"/>
        <mx:Button y="50" label="UnCaught Error" click="unCaught();" />
        <mx:TextArea id="msg" width="180" height="70"/>
    </mx:VBox>
</mx:Application>

Thanks

Subodh Joshi
  • 12,717
  • 29
  • 108
  • 202
Jefferson
  • 31
  • 1
2

I attached the event listener to the 'root', which worked for me:

sprite.root.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);

In the debug Flash Player this will still error, but in the non-debug version the error will appear in Flash Player's dialog box - and then the handler will respond. To stop the dialog box from appearing, add:

event.preventDefault();

so:

    private function onUncaughtError(event:UncaughtErrorEvent):void
    {
        event.preventDefault();
        // do something with this error
    }

I was using this in AIR, but I assume it works for standard AS3 projects too.

neave
  • 2,482
  • 1
  • 26
  • 18
0

Now you can, using loader info:

http://www.adobe.com/devnet/flex/articles/global-exception-handling.html

Checkout:

loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);

private function onUncaughtError(e:UncaughtErrorEvent):void
{
    // Do something with your error.
}
Subodh Joshi
  • 12,717
  • 29
  • 108
  • 202
Pablo
  • 456
  • 2
  • 7
  • 18