HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

AS3 AIR class robustness check

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
as3robustnessaircheckclass

Problem

I have a ActionScript 3 AIR class that I'd like you to check for robustness. I know it's quite a lot of code and It's not required that you review the full code, but maybe you see general problems in the way I handle exceptions or maybe you spot something that could make troubles.

The purpose of the Class is to load a local SWF and to run it within the AIR security sandbox. Before doing so, it might update the swf in two ways:

-
either there is a MyApp_update.swf present in the app-storage directory - in this case it should simply replace the current swf by this swf.

-
if that's not the case, it connects to a server and checks whether a new version is available by downloading a meta-info.xml and comparing the version number on the server with the version number of the local meta-info.xml

It's important that this part of the code is robust, since the rest of the application we can easily update remotely (in case this class here is doing it's job well).

```
package
{

import flash.desktop.NativeApplication;
import flash.display.Loader;
import flash.display.NativeWindow;
import flash.display.NativeWindowInitOptions;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.UncaughtErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.utils.ByteArray;

public class MyApp_Base extends Sprite
{
private var _remoteMetaRequest:URLRequest = new URLRequest("http://www.myServer.com/updater_test/my_app_meta.xml")
private var _remoteSwfRequest:URLRequest = new URLRequest("

Solution

After three and a half years, I guess your code turned out to be robust... even although your question went unanswered.

I can't answer your core question, but here are some side remarks:

if(remoteVersion>localVersion)
            updateSWF();
        else
            loadAndRunLocalSwf();


and

if(_progressWindow)
            _progressWindow.close();


Always add curly braces for if-else statements! It's just too easy to forget that they're not there and screw something up.

try{
            _remoteMetaXMLString = e.target.data;
            _remoteMetaXML = new XML(_remoteMetaXMLString);
            var localVersion:int = _localMetaXML.version;
            var remoteVersion:int = _remoteMetaXML.version;
        }
        catch(e:Error){
                showWarning("Warning", "The file " +_remoteMetaRequest.url +" is not correctly formatted. This error does not affect application execution, but prevents the application from being updated. If this error persists, please contact the application author. \n"+e.message);
                loadAndRunLocalSwf();
                return;     
        }


You seem to have some inconsistent indentation. See if your IDE supports automated formatting.

var ba:ByteArray = e.target.data;

        //if old backupfile exists, delete it
        var backup:File = new File("app-storage:/application/MyApp_backup.swf");
        if(backup.exists){
            try{
                backup.deleteFile();
            }
            catch(e:Error){
                showError("Error", "Error while deleting file "+backup.nativePath+" : \n"+e.message);
                return;
            }
        }

        //make current SWF the backup
        var appFile:File = new File("app-storage:/application/MyApp.swf");
        try{
            appFile.moveTo(appFile.parent.resolvePath("MyApp_backup.swf"));
        }
        catch(e:Error){
            showError("Error", "Error while creating backup of "+ appFile.nativePath+" . Make sure that there is only one instance of the MyApp running. If this error persists, please contact the application author. \n"+e.message);
            return;
        }

        //write the downloaded SWF to the disk
        var s:FileStream = new FileStream();
        try{
            appFile = new File("app-storage:/application/MyApp.swf");
            s.open(appFile, FileMode.WRITE);
            s.writeBytes(ba);


You declare a ByteArray, but then you don't use it until a good 30 lines later. Additionally, you keep redefining e as Error, where it was previously an event.

My compiler gives warning messages for this sort of thing. When you're concerned about the robustness of your code, I recommend you take some time to look at each and every warning that pops up for that bit of code. Automated code checking is there to help you, not to be whiny and annoying that you didn't color between the lines.

```
private function updateSwfLoaded(e:Event):void{
if(e.target.bytesLoaded!=e.target.bytesTotal){
trace("internet connection got interrupted while downloading remote MyApp.swf");
remoteSwfError(null);
return;
}
if(_progressWindow)
_progressWindow.close();
_progressWindow = null;

var ba:ByteArray = e.target.data;

//if old backupfile exists, delete it
var backup:File = new File("app-storage:/application/MyApp_backup.swf");
if(backup.exists){
try{
backup.deleteFile();
}
catch(e:Error){
showError("Error", "Error while deleting file "+backup.nativePath+" : \n"+e.message);
return;
}
}

//make current SWF the backup
var appFile:File = new File("app-storage:/application/MyApp.swf");
try{
appFile.moveTo(appFile.parent.resolvePath("MyApp_backup.swf"));
}
catch(e:Error){
showError("Error", "Error while creating backup of "+ appFile.nativePath+" . Make sure that there is only one instance of the MyApp running. If this error persists, please contact the application author. \n"+e.message);
return;
}

//write the downloaded SWF to the disk
var s:FileStream = new FileStream();
try{
appFile = new File("app-storage:/application/MyApp.swf");
s.open(appFile, FileMode.WRITE);
s.writeBytes(ba);
s.close();
}
catch(e:Error){
showError("Error", "Error while writing MyApp.swf to disk. Will try to restore backup. If this error persists, please contact the application author. \n"+e.message);
backup = new File("app-storage:/application/MyApp_backup.swf");
backup.moveTo(backup.parent.resolvePath("MyApp.swf"));
return;
}

if(_localSwfUpdateFile.exists){//the update was performed by a local update file
try{

Code Snippets

if(remoteVersion>localVersion)
            updateSWF();
        else
            loadAndRunLocalSwf();
if(_progressWindow)
            _progressWindow.close();
try{
            _remoteMetaXMLString = e.target.data;
            _remoteMetaXML = new XML(_remoteMetaXMLString);
            var localVersion:int = _localMetaXML.version;
            var remoteVersion:int = _remoteMetaXML.version;
        }
        catch(e:Error){
                showWarning("Warning", "The file " +_remoteMetaRequest.url +" is not correctly formatted. This error does not affect application execution, but prevents the application from being updated. If this error persists, please contact the application author. \n"+e.message);
                loadAndRunLocalSwf();
                return;     
        }
var ba:ByteArray = e.target.data;

        //if old backupfile exists, delete it
        var backup:File = new File("app-storage:/application/MyApp_backup.swf");
        if(backup.exists){
            try{
                backup.deleteFile();
            }
            catch(e:Error){
                showError("Error", "Error while deleting file "+backup.nativePath+" : \n"+e.message);
                return;
            }
        }

        //make current SWF the backup
        var appFile:File = new File("app-storage:/application/MyApp.swf");
        try{
            appFile.moveTo(appFile.parent.resolvePath("MyApp_backup.swf"));
        }
        catch(e:Error){
            showError("Error", "Error while creating backup of "+ appFile.nativePath+" . Make sure that there is only one instance of the MyApp running. If this error persists, please contact the application author. \n"+e.message);
            return;
        }

        //write the downloaded SWF to the disk
        var s:FileStream = new FileStream();
        try{
            appFile = new File("app-storage:/application/MyApp.swf");
            s.open(appFile, FileMode.WRITE);
            s.writeBytes(ba);
private function updateSwfLoaded(e:Event):void{
        if(e.target.bytesLoaded!=e.target.bytesTotal){
            trace("internet connection got interrupted while downloading remote MyApp.swf");
            remoteSwfError(null);
            return;
        }
        if(_progressWindow)
            _progressWindow.close();
        _progressWindow = null;

        var ba:ByteArray = e.target.data;

        //if old backupfile exists, delete it
        var backup:File = new File("app-storage:/application/MyApp_backup.swf");
        if(backup.exists){
            try{
                backup.deleteFile();
            }
            catch(e:Error){
                showError("Error", "Error while deleting file "+backup.nativePath+" : \n"+e.message);
                return;
            }
        }

        //make current SWF the backup
        var appFile:File = new File("app-storage:/application/MyApp.swf");
        try{
            appFile.moveTo(appFile.parent.resolvePath("MyApp_backup.swf"));
        }
        catch(e:Error){
            showError("Error", "Error while creating backup of "+ appFile.nativePath+" . Make sure that there is only one instance of the MyApp running. If this error persists, please contact the application author. \n"+e.message);
            return;
        }

        //write the downloaded SWF to the disk
        var s:FileStream = new FileStream();
        try{
            appFile = new File("app-storage:/application/MyApp.swf");
            s.open(appFile, FileMode.WRITE);
            s.writeBytes(ba);
            s.close();
        }
        catch(e:Error){
            showError("Error", "Error while writing MyApp.swf to disk. Will try to restore backup. If this error persists, please contact the application author. \n"+e.message);
            backup = new File("app-storage:/application/MyApp_backup.swf");
            backup.moveTo(backup.parent.resolvePath("MyApp.swf"));
            return;
        }

        if(_localSwfUpdateFile.exists){//the update was performed by a local update file
            try{
                _localSwfUpdateFile.deleteFile();
            }
            catch(e:Error){
                showError("Error", "Could not delete " + _localSwfUpdateFile.nativePath + ". If this error persists, please contact the application author. \n"+e.message);
                return;
            }
        }
        else{   
            //write the downloaded MetaData to the disk
            try{
                s.open(_localMetaFile,FileMode.WRITE);
                s.writeUTFBytes(_remoteMetaXMLString);
                s.close();
            }
            catch(e:Error){
                showError("Error", "Error while writing "+ _localMetaFile.nativePath+" to disk. Make sure that there is only one instance of the MyApp running. If this error persists, please contact the application author.\n"+e.message);
                return;
            }
        }

        //run the loaded SWF
        loadAndRunLocalSwf();
    }

Context

StackExchange Code Review Q#2952, answer score: 2

Revisions (0)

No revisions yet.