Global Error Handling in Flex

January 4th, 2010 Brian Gray, Consultant  (email the author)

This entry is part 6 of 6 in the series Flex Development

UPDATE (8/17/2011): This post was originally written for Flex 3. As comments below indicate, Flex 4 (and Flash Player 10) support more robust options for global error handling. This article presents my favorite approach for implementing error handling in a Flex 4 application.

I have worked on a few large Flex applications, and almost everything about the platform delights me — it is quick to prototype, powerful in creating rich UIs.  But it often frustrates me how difficult it is to handle run-time errors.  As the application scales, it becomes harder and harder to ensure that it will never emit a run-time error, and the default Flash Player behavior of freezing and not providing any user feedback will not cut the mustard. The approach I have found to work best is as follows (until a future beta of Flash Player 10 supports this out of the box). Jörg Birkhold describes how to tell the call later dispatcher to throw an event any time an error is thrown.


private function onPreinitialize():void {
  // setup global error handling
  UIComponentGlobals.catchCallLaterExceptions = true;
  systemManager.addEventListener("callLaterError", handleErrors);
}

I add an event handler in my Main application, doing the following:

  • Print the stack trace to the console for debugging, since it will no longer print by default
  • Pop an alert up to the user. Depending on how the error is thrown, this may or may not make it to the screen, but it will ensure the screen glosses over to prevent any further interaction.
  • If JavaScript is available, call a JavaScript function.  You can do anything you want here, but my preference is to redirect the user to an error page that tells them something went wrong, and links them to the correct page to restart where they left off.

public function handleErrors(event:Event):void {
  if (event is DynamicEvent && event.hasOwnProperty("error")) {
    // you could also send this back to your server
    var error:Error = DynamicEvent(event).error as Error;
    trace("Error!\n" + error.getStackTrace());
    Alert.show("There has been an error in the application", "", Alert.OK);

    if (ExternalInterface.available) {
      ExternalInterface.call("handleApplicationError");
    }
  }
}

Download the full demo. To create this project in Flex Builder: Create a new Flex Project. Right click and select Import, select Archive File, select this file, and import all contents.

Share and Enjoy:
  • Digg
  • Reddit
  • del.icio.us
  • Google
  • description
  • LinkedIn

Entry Filed under: Agile and Development

11 Comments Add your own

  • 1. chandra shekhar  |  January 9th, 2010 at 5:05 am

    Nice article.
    “Download the full demo” link not working

  • 2. Brian Gray  |  March 3rd, 2010 at 5:22 pm

    @chandra: Thanks! Seems like the link is working now. Let me know if you still have trouble with it.

  • 3. Agraj  |  May 31st, 2010 at 6:03 am

    Hi Brian,

    Thanks, I was looking for exactly the same thing.

    However, this technique is not working in my project and I have no wild idea why is it so ?

    In case of an error, the control never reaches the error handler. :(

    Any ideas ?

    Regards

  • 4. Brian Gray  |  June 2nd, 2010 at 4:52 pm

    Hi Agraj,

    Are you able to run the demo to get the desired effect?

    It may be an issue with where the errors are originating from. This post finds that if an error is thrown by an event dispatcher, there is no way to catch it on the initiating thread. That is why, in my demo, I use this click handler:

    click="callLater(throwError)"

    Instead of:

    click="throwError()"

    Typically in a large MVC application, this is not an issue, as the handlers are very simple and just dispatch events. Most frameworks (Mate, Cairngorm, etc.) encourage this pattern. However there are certainly times where this is not the case and care has to be taken to ensure that the exception code will be in the callLater queue.

  • 5. Agraj  |  October 5th, 2010 at 1:49 am

    Hi Brian,

    Thanks for the tip. With the understanding that “there is no way to catch it on the initiating thread” I’m able to call my error handler using callLater method. :-)

    I would highly appreciate if you point me to some resources regarding different use cases of callLater()

    Regards

  • 6. Brian Gray  |  October 6th, 2010 at 9:33 am

    Hi Agraj,

    As Jimmy” Gianninas points out, every Flex movie is made up of only two frames, one for initialization and one in which the application executes. The latter is redrawn many times per second — some Flex APIs have immediate effects and others have effects on later refreshes.

    callLater() allows you to queue up a method to be called on the next screen refresh. It is often used to wait until some UI work can be done. In this demo, I use it to separate the error from the click handler.

    This article from Adobe has more examples:
    http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7b06.html

  • 7. Marcus  |  November 19th, 2010 at 1:41 am

    catchCallLaterExceptions property

    catchCallLaterExceptions:Boolean [read-write]
    A global flag that can is used to catch unhandled exceptions during execution of methods executed via callLater

    So, if there’s a error occured not in calllater function, then handleErrors above will not execute.
    so, to catch and handle global errors througth catchCallLaterExceptions is not a smart way.

  • 8. Brian Gray  |  November 19th, 2010 at 11:17 am

    @Marcus, your point is well-taken. In FP10, it seems like you can handle any uncaught exception. But prior to that version (using FP9 and Flex 3.5, as I am here), the best you can do is handle callLater exceptions.

    In a typical application, those will be the majority use case. Most of your heavy-lifting logic will be in handlers that are in RPC calls or similar calls that will be in some ways invoked in a callLater-fashion. But I agree-it is not the best solution. If you are on FP10, use the above link.

  • 9. smithfox  |  December 14th, 2010 at 12:36 am

    Hello Brain,

    I use your solution and FP10.1 loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);

    But all of them can not catch the Error from a Module.

    Do you have some idea about that?

  • 10. Brian Gray  |  December 20th, 2010 at 11:43 am

    @smithfox, I have not used this error handling solution across multiple modules. If you figure something out, please post back here and let me know how you got it to work!

  • 11. Avier5  |  March 8th, 2011 at 10:19 am

    regarding catching errors from modules: few open bugs on it on Adobe’s bugzilla, please look for them and vote!!! We need this fix ASAP!

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Pages

Categories

Most Recent Posts

Feeds

  Subscribe in a reader

Calendar

January 2010
M T W T F S S
« Dec   Feb »
 123
45678910
11121314151617
18192021222324
25262728293031

Tags