Martin Asenov
Martin Asenov

Reputation: 1298

In ActionScript3, how to catch ErrorEvent that I've dispatched?

At some points in my application, I've a try-catch block such as: This happens inside classes that are not in the display list (not Sprites, nor any kind of DisplayObject), but extend EventDispatcher. Those classes reside in externally loaded SWF (in case that matters).

try {
    ... some logic that may throw Error
} catch (e:Error) {
    var errorEvent:ErrorEvent = new ErrorEvent(ErrorEvent.ERROR, true);
    errorEvent.text = e.getStackTrace();
    dispatchEvent(errorEvent);
}

In the root class, this is what I have:

loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtErrorHandler);
loaderInfo.uncaughtErrorEvents.addEventListener(ErrorEvent.ERROR, onErrorEventHandler);
stage.addEventListener(ErrorEvent.ERROR, onErrorEventHandler);

protected function onUncaughtErrorHandler(event:UncaughtErrorEvent):void
{
    var message:String; 
    if (event.error is Error) {
        message = event.error.getStackTrace();
    } else if (event.error is ErrorEvent) {
        message = ErrorEvent(event.error).text;
    } else {
        message = event.error.toString(); 
    }

    trace(message);
}

protected function onErrorEventHandler(event:ErrorEvent):void
{
    trace(event.text);
}

Neither handlers are called, but those error events bubble up and I see them in console, and as popups in debug mode, but how do I listen to them in a root class?

I do this because I don't want the error to interrupt execution of the main thread or the particular business logic.

Upvotes: 1

Views: 339

Answers (2)

Aleksey Linetskiy
Aleksey Linetskiy

Reputation: 473

I think what you are looking for is a listener to uncaught error events. Here is an example of adding it in your root class:

this.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onGlobalErrors);

EDIT BY LDMS

The following works in FlashPro:

loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR,function(e:Event){
    trace("I Caught an Error");
});

var err:ErrorEvent = new ErrorEvent(ErrorEvent.ERROR,true);

var obj:EventDispatcher = new EventDispatcher();

obj.dispatchEvent(err);

Upvotes: 2

Crabar
Crabar

Reputation: 1857

If your class is on stage you can add event listener for ErrorEvent.ERROR to stage. Any dispatched event will go up to the stage through all its parents.

Example of code:

// some initialize
stage.addEventListener("lol", lolHandler);
// dispatching
private function button1_clickHandler(event:MouseEvent):void
{
    // second parameter responsible for bubbling and MUST be true
    dispatchEvent(new Event("lol", true)); // on mouseClick we dispatch custom event
}

private function lolHandler(event:Event):void
{
     trace("We got it! Lol!);
}

P.S. Article in the comment is really useful. Recommend it to read.

// UPDATE

Alternative variant can be in dispatching event from some singleton. For example:

    public class ErrorHandler extends EventDispatcher {
        private static var _instance:ErrorHandler;

        public static function get instance():ErrorHandler {
            if (!_instance)
                _instance = new ErrorHandler(new PrivateConstructor());

            return _instance;
        }

        public function ErrorHandler(value:PrivateConstructor) {
            addEventListener(ErrorEvent.ERROR, errorHandler);
        }

        private function errorHandler(event:ErrorEvent):void {
            // some code
        }
    }
}
class PrivateConstructor {}

.... and dispatching
ErrorHandler.instance.dispatchEvent(new ErrorEvent());

Upvotes: 0

Related Questions