# AS3 AIR class robustness check

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:

1. 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.

2. 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.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.URLRequest;
import flash.system.ApplicationDomain;
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("http://www.myServer.com/updater_test/MyApp.swf");

private var _localSwfFile:File = new File("app-storage:/application/MyApp.swf");
private var _localSwfUpdateFile:File = new File("app-storage:/application/MyApp_update.swf");
private var _localMetaFile:File = new File("app-storage:/application/my_app_meta.xml");
private var _localMetaXML:XML;
private var _remoteMetaXMLString:String;
private var _remoteMetaXML:XML;

private var _progressWindow:NativeWindow;

public function MyApp_Base()
{

//check if a local swf update file is present. if so, replace the current version with it, delete the update file and skip checking the server
if(_localSwfUpdateFile.exists){

try{
}
catch(e:Error){
return;
}
}
else{ //check the server for a new update
var s:FileStream = new FileStream();
try{
_localMetaXML = new XML(xmlString);
s.close();
}
catch(e:Error){
showWarning("Warning", "There was an Error while loading the file " +_localMetaFile.nativePath +". This could mean that your installation is corrupted. The updateserver is not checked for updates: \n"+e.message);
return;
}

try{
}
catch(e:Error){
showWarning("Warning", "There was an Error while loading the file " +_remoteMetaRequest.url +". 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);
return;
}
}
}

remoteXMLError(null);
return;
}

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);
return;
}

if(remoteVersion>localVersion)
else
}

private function remoteXMLError(e:Event):void{
}

try{
}
catch(e:Error){
showWarning("Warning", "There was an Error while loading the file " +_remoteSwfRequest.url +". 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);
return;
}
}

private function remoteSwfError(e:Event):void{
if(_progressWindow){
try{
_progressWindow.close();
_progressWindow = null;
}
catch(e:Error){}
}
}

private function localUpdateError(e:Event):void{
}

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;
}

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{
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;
}
}

}

context.applicationDomain = ApplicationDomain.currentDomain;

var s:FileStream = new FileStream();
try{
var ba:ByteArray = new ByteArray();
s.close();

}
catch(e:Error){
return;
}
}

private function onUncaughtError(e:UncaughtErrorEvent):void
{
e.preventDefault();
var error:Error = e.error;
showWarning("Uncaught Error:", error.message);
return;
}

private function showError(title:String, msg:String):void{
var errorBox:ErrorBox = new ErrorBox(msg);

var nativeWinOpt:NativeWindowInitOptions = new NativeWindowInitOptions();
nativeWinOpt.maximizable = false;
nativeWinOpt.minimizable = true;
nativeWinOpt.resizable = false;

var window:NativeWindow = new NativeWindow(nativeWinOpt);
window.stage.scaleMode = StageScaleMode.NO_SCALE;
window.stage.align = StageAlign.TOP_LEFT;
window.width = errorBox.width;
window.height = errorBox.height;
window.title = title;
window.activate();
}

private function showWarning(title:String, msg:String):void{
var warningBox:WarningBox = new WarningBox(msg);

var nativeWinOpt:NativeWindowInitOptions = new NativeWindowInitOptions();
nativeWinOpt.maximizable = false;
nativeWinOpt.minimizable = true;
nativeWinOpt.resizable = false;

var window:NativeWindow = new NativeWindow(nativeWinOpt);
window.stage.scaleMode = StageScaleMode.NO_SCALE;
window.stage.align = StageAlign.TOP_LEFT;
window.width = warningBox.width;
window.height = warningBox.height;
window.title = title;
window.activate();
}

private function showProgressWindow(msg:String):void{
_progressBox.setMessage(msg);
_progressBox.setProgress(0.0);

var nativeWinOpt:NativeWindowInitOptions = new NativeWindowInitOptions();
nativeWinOpt.maximizable = false;
nativeWinOpt.minimizable = true;
nativeWinOpt.resizable = false;

_progressWindow = new NativeWindow(nativeWinOpt);
_progressWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
_progressWindow.stage.align = StageAlign.TOP_LEFT;
_progressWindow.width = _progressBox.width;
_progressWindow.height = _progressBox.height;
_progressWindow.activate();
}

}

if(_progressWindow){
try{
_progressWindow.close();
_progressWindow = null;