I am loading a swf into another swf using swfloader, I want to catch all the exceptions thrown by the inner swf, is it doable?
Here are some basics that may help. In short, you cannot use try/catch here.
Errors in loading external content cannot be caught with try..catch..finally statements. Instead you have to create event handlers to handle and “catch” the error events. If you do not have an event listener assigned to an error event and that error occurs, the Flash player will inform you of the unhandled error event.
// creating listeners for error events handles
// asynchronous errors
target.addEventListener(ErrorEvent.TYPE, handler);
function handler(event:ErrorEvent):void {
// handle error
}
If you want to invoke your own asynchronous errors, all you need to do is dispatch an event using dispatchEvent that is of the type ErrorEvent. When an unhandled ErrorEvent reaches the Flash player when authoring in Flash, the output window will display the error.
target.dispatchEvent(new ErrorEvent(”type”));
As of Flash 10.1 it is now possible to catch all errors thrown by both the main swf and any swfs loaded inside of it.
To do this you need to listen for an UncaughtErrorEvent dispatched from the loaderInfo.uncaughtErrorEvents object, like so:
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, handleUncaughtErrors);
function handleUncaughtErrors(e:UncaughtErrorEvent):void
{
e.preventDefault();
}
Please use with caution, as this will suppress all errors from being shown by the debug version of the player, and the flashlog.txt.
Related
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.
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!
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.
Does addEventListener(ErrorEvent.ERROR, handler) handle all type of error event, for example, IOErrorEvent.IO_ERROR, SecurityErrorEvent.SECURITY_ERROR, and other all error events?
I'm looking for addEventListener() version of try catch(e:Error)(e:Error can catch all type of errors).
You can add error handlers to the UncaughtErrorEvents object:
loaderInfo.uncaughtErrorEvents.addEventListener(
UncaughtErrorEvent.UNCAUGHT_ERROR, errorHandler);
function errorHandler(e:UncaughtErrorEvent):void {
if(event.error is Error) {
// handle error
}
// suppress error dialog
e.preventDefault();
}
This is only possible in Flash Player 10.1 and above.
You can find more information here: flash.events.UncaughtErrorEvents
This can be especially helpful for handling exceptions from a loaded SWF. I assume you have a good reason for doing this?
Each event type is registered as a different String, so the only way to catch all events of varying types is to listen for uncaught errors that get relayed by a special UncaughtErrorEvents dispatcher. Notably, this exists on any DisplayObject's loaderInfo property # DisplayObject.loaderInfo.uncaughtErrorEvents.
Demonstrating 3 ways to receive uncaught errors...
private var loader:Loader = new Loader();
public function MyDocumentClass ()
{
// 1: Listen for all errors in the application:
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
// 2: Listen for errors from the child swf being loaded:
loader.load(new URLRequest("file.swf"));
loader.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
// 3: Listen for errors from Loader doing the loading:
loader.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
// This seems like it would work, but wasn't working in tests I ran:
stage.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
}
private function uncaughtErrorHandler(event:UncaughtErrorEvent):void
{
if (event.error is Error)
{
var error:Error = event.error as Error;
// do something with the error
}
else if (event.error is ErrorEvent)
{
var errorEvent:ErrorEvent = event.error as ErrorEvent;
// do something with the error
}
else
{
// a non-Error, non-ErrorEvent type was thrown and uncaught
}
}
From Adobe's documentation...
An UncaughtErrorEvent (extends ErrorEvent) object is dispatched by an
instance of the UncaughtErrorEvents class when an uncaught error
occurs. An uncaught error happens when an error is thrown outside of
any try..catch blocks or when an ErrorEvent object is dispatched with
no registered listeners. The uncaught error event functionality is
often described as a "global error handler."
The UncaughtErrorEvents object can be accessed in two ways...
LoaderInfo.uncaughtErrorEvents -- to detect uncaught errors in code defined in the same SWF.
An object that dispatches an uncaughtError event when an unhandled
error occurs in the SWF that's loaded by this Loader object. An
uncaught error happens when an error is thrown outside of any
try..catch blocks or when an ErrorEvent object is dispatched with no
registered listeners.
Note that a Loader object's uncaughtErrorEvents property dispatches
events that bubble through it, not events that it dispatches directly.
It never dispatches an uncaughtErrorEvent in the target phase. It only
dispatches the event in the capture and bubbling phases. To detect an
uncaught error in the current SWF (the SWF in which the Loader object
is defined) use the LoaderInfo.uncaughtErrorEvents property instead.
Loader.uncaughtErrorEvents -- to detect uncaught errors in code defined in the SWF loaded by a Loader object.
An object that dispatches an uncaughtError event when an unhandled
error occurs in code in this LoaderInfo object's SWF file. An uncaught
error happens when an error is thrown outside of any try..catch blocks
or when an ErrorEvent object is dispatched with no registered
listeners.
This property is created when the SWF associated with this LoaderInfo
has finished loading. Until then the uncaughtErrorEvents property is
null. In an ActionScript-only project, you can access this property
during or after the execution of the constructor function of the main
class of the SWF file. For a Flex project, the uncaughtErrorEvents
property is available after the applicationComplete event is
dispatched.
Some important details from Adobe's documentation...
When an uncaughtError event happens, even if the event is handled,
execution does not continue in the call stack that caused the error.
If the error is a synchronous error, any code remaining in the
function where the error happened is not executed. Consequently, it is
likely that when an uncaught error event happens, your application is
in an unstable state. Since there can be many causes for an uncaught
error, it is impossible to predict what functionality is available.
For example, your application may be able to execute network
operations or file operations. However, those operations aren't
necessarily available.
When content is running in a debugger version of the runtime, such as
the debugger version of Flash Player or the AIR Debug Launcher (ADL),
an uncaught error dialog appears when an uncaught error happens. For
those runtime versions, the error dialog appears even when a listener
is registered for the uncaughtError event. To prevent the dialog from
appearing in that situation, call the UncaughtErrorEvent object's
preventDefault() method.
if you want to catch all the errors in your application you should definitely use try-catch blocks. By using addEventListener you are adding listener to a specific object and you will catch the errors only there.
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).