patternMinor
AS3 AIR class robustness check
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
-
if that's not the case, it connects to a server and checks whether a new version is available by downloading a
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("
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.xmlIt'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:
and
Always add curly braces for if-else statements! It's just too easy to forget that they're not there and screw something up.
You seem to have some inconsistent indentation. See if your IDE supports automated formatting.
You declare a
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{
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.