Search code examples
actionscript-3air

Why isn't my exception being caught?


This is the stack trace I get:

[Fault] exception, information=Error: Directory id 3 already in use
at cantrips.assets.index::AssetIndex/dirIdChanged()[/home/luismasuelli/Proyectos/flash-assets-index-ritual/assets-index-loader/src/cantrips/assets/index/AssetIndex.as:72]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at cantrips.assets.index::AssetDirectory/set id()[/home/luismasuelli/Proyectos/flash-assets-index-ritual/assets-index-loader/src/cantrips/assets/index/AssetDirectory.as:68]
at Main/updateSelectedDirectory()[/home/luismasuelli/Proyectos/flash-assets-index-ritual/assets-index-editor/src/Main.mxml:192]
at Main/__dirUpdateCurrent_click()[/home/luismasuelli/Proyectos/flash-assets-index-ritual/assets-index-editor/src/Main.mxml:401]

This is the implementation of Main/updateSelectedDirectory():

    private function updateSelectedDirectory():void {
        try {
            var newId:uint = uint(dirId.text);
            var newName:String = StringUtil.trim(dirName.text);
            var selectedDirectory:AssetDirectory = assetBrowserTree.selectedItem as AssetDirectory;
            if (selectedDirectory) {
                selectedDirectory.id = newId;
                selectedDirectory.name = newName;
                assetBrowserTree.expandItem(selectedDirectory.parent, false);
                assetBrowserTree.expandItem(selectedDirectory.parent, true);
            }
        } catch (error:Error) {
            Alert.show(error.message, "Cannot update");
        }
    }

Why is not the exception being caught by try {} catch(error:Error) {}?.

The exception is an exception created by me, with a well-understood scenario where it is triggered (I created the exception and designed those scenarios and I am testing them; exception is triggered as I expect). I also tried using the exact name of the exception (AssetIndexError) in the catch block, and no confusion or ambiguous name exists (this means: there's no another AssetIndexError class declared elsewhere I could be importing instead of this).

Explanation:

  • cantrips.assets.index is code I have control over.
  • Main/* is the main window. I also have control over that code.

Screenshot:

Screenshot


Solution

  • If you look at your stack, you'll see the error is not being thrown in the code shown (which is near the bottom of the stack), but here:

    dirIdChanged at AssetIndex.as:72

    Further down in the stack you'll see the following:

    at flash.events::EventDispatcher/dispatchEvent()

    This means that stack was asynchronous in between AssetDirectory.set id() and AssetIndex.dirIdChanged()

    When you add an event handler, all code in the current block will usually run prior to the event handler code (as they are not in the same thread).

    So in this case, all your code in the try/catch will have run before the event handler's code - which is why the error is not being caught.

    Any time you are handling an event, you will need to have another try/catch, or use an asynchronous error handling technique.