Flex/AIR - Displaying ActionScript errors in a release application - actionscript-3

When I run a Flex/AIR application in debug mode and an error occurs, I see this:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
However when the application has been installed as a release build and the same error happens, I don't see an error message.
Is it possible for my application to either save these types of errors to a log file or email them to me?

I have managed to implement this myself using the UncaughtErrorEvent and airxmail classes.
It was a simple case of adding the UncaughtError event to loaderInfo (within a method which is called by the FlexEvent.APPLICATION_COMPLETE event). Using these two classes, the application emails the runtime errors to me as and when they occur, in release mode only as the UncaughtError event does not fire in debug mode.

If you want to log your uncaught errors you can use the uncaughtError event.
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR,handleGlobalErrors);
function handleGlobalErrors( evt : UncaughtErrorEvent ):void
{
//code that saves error to log or send by email..
evt.preventDefault();
}
You can find more information about this feature here http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/UncaughtErrorEvent.html.
Also beware that if you use this in Debug mode all your errors will be caught by the handleGlobalErrors function so keep that in mind.

Related

AS3, Flash: Accessing error messages text in code

I'm working on some flash app. Now, to test customer side of it I can use Flash Player debugger version that will save logs and show error messages. When it's deployed on the customer side - they will have a regular Flash Player version which means I will have no access to error messages if errors will happen. So I would like to equip it with some tool that would capture all of my trace messages in code and errors text. As for trace messages that's fairly simple, I just override the function in my code so it sends a POST request with trace message to a logger server, but how can I get a hold of the error message? Is there a known approach to this or some trick that somebody can suggest?
You can install the debug version of flash as your browser's default (in Chrome, you must disable the built-in player), so if you wanted to test user experience and debug, this would be the ideal solution.
However, to answer your question: there's no method for universally catching all errors, and redirecting them (that I know of). You'd have to encapsulate problem code ahead of time with try...catch statements, and send the property back on catch. For example:
try {
this["foo"]();
} catch (e:Error) {
trace(e);
}
In the debug version, the traced value would be TypeError: Error #1006: value is not a function. And while the standard version will only output TypeError: Error #1006, (a notably less descriptive error), what we're missing is any reference to where the error occured. To get this, we need to use Error.getStackTrace() to see the call stack and the line where the error occurred. In debug, this outputs the following:
TypeError: Error #1006: value is not a function.
at Shell_fla::MainTimeline/init()[C:\Projects\shell.as:91
In the standard client, we get a dissapointing null. In short, you cannot get any valuable info from the client versions.
The best advice I can give is to write around your problem code with your own custom error reports. For example, catch IO errors and trace the file it failed to load, or if you're expecting an object.foo, first try if (object.hasOwnProperty("foo")) { // do something } else { trace("foo not found in " + object.name) }. Code defensively.
Cheers,
I've discovered this post on StackOverflow:
How to catch all exceptions in Flex?
It answers my question, strange that I haven't ran into it while I was googling prior to asking.

Citrus Engine Flash Game not compiling correctly

Im developing a flash game based on the citrus engine for a uni project.
All of it is done and handed in but im trying to compile the entire project into a release for web.
In flahs builder ive gone file --> export --> release build and compiled the game.
the .swf file opens up fine and initiatze the spirte menu but when clicking the start game button it begins to initiate the game state but then hangs up on a solid colour, in flash debugger im getting these errors
SecurityError: Error #2000: No active security context.
Started
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.citrusengine.utils::ObjectMaker$/FromMovieClip()
at GameState/initialize()
at com.citrusengine.core::CitrusEngine/handleEnterFrame()
SecurityError: Error #2000: No active security context.
Started
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.citrusengine.utils::ObjectMaker$/FromMovieClip()
at GameState/initialize()
at com.citrusengine.core::CitrusEngine/handleEnterFrame()
Any suggestion appreciated
Error #2000 is usually a file not found error. You can get more info from running an IOErrorEvent like so:
myLoader.addEventListener(IOErrorEvent.IO_ERROR, IOError)
function IOError(e:IOErrorEvent):void {
trace(e.text);
}
Likely an issue with pathing to the correct file.
Error #1009 is likely a domino effect of not being able to work on the asset that hasn't been loaded due to the IOError. It could also be an issue if you're loading other SWFs to the stage and those child SWFs attempt to utilize the stage before it's ready, in which case you'd want to only start your scripts until after the addedToStage event has fired. You can set that up like so:
if (this.parent is Stage) {
stageReady();
} else {
addEventListener("addedToStage", stageReady);
}
function stageReady(e:Event = null):void {
// begin your setup code here.
}
The logic here being that if your swf is not encapsulated inside a loader, the parent object should be the stage, otherwise, you can safely add a listener to the loaded swf's timeline that listens for the addedToStage event.
Maybe the following will resolve your problem:
Wrap all the init code to a custom function (lets say: initFunctionOfApplication). Set a delay timer before this init function is called. It's a issue I've had before, and got it fixed with a small delay... Maybe this will fix your problem.
setTimeout(function():void{initFunctionOfApplication();}, 3000);
Keep us posted!

event listener for flex/air action script errors

I'm trying to add an event listener to my air application that would prevent the "ActionScript error" window from appearing, so I can handle the error within my application.
I was able to find a little information about this from adobe. I'm just not sure what I should be listening for.
It depends quite a lot on what error is thrown, and why.
Your best bet is to carefully read the ActionScript documentation and add listeners to react to all of the errors that have explicit ErrorEvents (such as IOErrorEvent and SecurityErrorEvent). Those are usually related to network and/or file access, and security issues.
For most other errors, there is the try {} catch() {} finally {} statements. This tutorial might be a good place to start.
And if all else fails, there's UncaughtErrorEvent.
But you should really be using that one as a last resort, not as a magic bullet - the best error handling is a) trying to prevent errors from being thrown in the first place (make sure all variables are properly initialized, test for null, etc.), and b) handling expected runtime errors by catching them explicitly, in order to keep the application running and stable.
You have a couple options. As you know, exception handling is not always possible for certain asynchronous operations.
First off, you need to know what object is responsible for the asynchronous operation that is causing the error. The most sensible approach would be to add the necessary error event handlers to this object.
For instance, a URLLoader performs asynchronous operations; and it's failure can only be handled by adding error event listeners. For example:
var loader: URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, completeHandler);
loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
Another 'catch-all' option is to take advanage of the new UncaughtErrorEvent feature of Flash Player 10.1. For this to work, you need to attach the uncaught error handler to the loader of the main application; this will catch everything! For example:
loader.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, loaderErrorHandler);
private function loaderErrorHandler(e:UncaughtErrorEvent):void {
if(event.error is Error) {
// handle error from embedded SWF
}
// suppress error dialog
e.preventDefault();
}
The last option may not be the best approach as it promotes the swallowing of exceptions instead of addressing and handling the problem properly; nevertheless it can be useful in certain unique circumstances (embedding SWFs).
The window won't appear if you're running the standard version of Flash Player.
It will manifest only as a dialog box on the debugger versions of the
browser plug-ins and stand-alone players, as a message in the output
panel in the authoring player, and as an entry in the log file for
Adobe Flex Builder 3. It will not manifest at all in the release
versions of Flash Player or AIR.
Source : here.

Handling Security Errors in AS3

I am using an imported class for a vimeo player in AS3, it is the official vimeo player api (vimeo.com). I want to handle any Security Errors that an instance of the class throws (they get thrown when the obect fails to load an external URL for a video). This is what I have got:
var clipPlayer = new VimeoPlayer("5d22d3942a54d7c75b931bab4a911857", videoID[clickedClip], fullVideoWidth, fullVideoHeight, "10", 2);
clipPlayer.addEventListener(SecurityErrorEvent.SECURITY_ERROR , vimeoError);
Later in the code ofcourse, I've got the function that handles the event:
function vimeoError (e : SecurityErrorEvent) : void {
trace("vimeo player failed to load");
}
This all seems straight forward, but yet the Error Handler is not firing. I must be missing something here... Maybe you can't register this kind of event listener on a VimeoPlayer object. However, I am pretty certain it is the VimeoPlayer object throwing them. Here is an example of what I am getting:
Error opening URL
'http://api.vimeo.com/moogaloop_api.swf?oauth_key=5d22d3942a54d7c75b931bab4a911857&clip_id=21185860&width=500&height=281&fullscreen=0&fp_version=10&api=1&cache_buster=565.7249609939754'
SecurityError: Error #2000: No active security context.
Dispatched error events are separate from thrown Errors. In many cases both kinds can occur, and then you need to listen for the former and catch the latter with a try statement around the code that may throw. The error you quote seems to be of the thrown variety (as events typically stringize to something involving square brackets).

Flash AS3 security errors attempting to load chromeless YouTube

I am getting flash-base security errors when attempting to load a chromeless YouTube swf...
Warning: Domain www.youtube.com does not explicitly specify a meta-policy, but Content-Type of policy file http://www.youtube.com/crossdomain.xml is 'text/x-cross-domain-policy'. Applying meta-policy 'by-content-type'.
Error: Request for resource at http://www.youtube.com/apiplayer?version=3 by requestor from http://... is denied due to lack of policy file permissions.
*** Security Sandbox Violation ***
Connection to http://www.youtube.com/apiplayer?version=3 halted - not permitted from http://...
I've attempted all relevant variations of Security.loadPolicyFile and Security.allowDomain, but I continue to get these errors.
If I ignore these trace errors (I get no callback errors from the Loader) and attempt to use the player (via loader.content during the Loader's Event.INIT), then any attempts to access the YouTube APIs causes a crash.
If I look at my player (Object) variable in a debugger, I see that it is actually a com.goggle.youtube.application::SwfProxy which is derived from Sprite. Outside of the standard Sprite vars and functions, it contains enableJsApi = false, loader = null, and player = "http://s.ytimg.com/yt/swfbin/apiplayer3-vfljSpMoI.swf"
But attempts to call functions such as player.setSize or player.loadVideoByUrl will cause a crash such as...
Exception thrown (TypeError: Error #1006: setSize is not a function.
Please advise.
I have worked with the Chromeless player before and gotten these errors. They are so frustrating. A number of the errors can be ignored because YouTube still hasn't renewed their default policy file.
Whevener you try to add any mouse event listeners to the gadget directly you will get errors that will cripple the runtime process. What I had to do to add mouse interactivity was to add a sprite above the movie clip with a hole where their logo shows up (so that someone can still click their logo) and then add event listeners to your own srite.
Hope this helps.
What finally worked to remove the errors was specifying... LoaderContext(false, new ApplicationDomain())