Debugging AS 3.0 - actionscript-3

I'm in need of some insight to debugging the following oddity that i'm experiencing. This small block of code has been working correctly for around 2 months and all of a sudden it no longer functions as expected and i don't know why as I've made no changes to it recently.
//Start Extract Calling Class method
//Magic Trace #1 comes much earlier in class init
trace("pathArr: "+pathArr); //<-- Magic trace #2
instance.trRoot.selMission.SaveMission(selFile,pathArr);
//End Extract Calling Class method
public function SaveMission(fileName:String=null, pathArr:Array=null):void{
trace("pathArr: "+pathArr);
if(pathArr != null){
trace("pathArr: "+pathArr);
trace("LastFP: "+pathArr[pathArr.length-1]);
Utils._AddToVirtualFileSystem(fileName,pathArr[pathArr.length-1],"File",Utils._GetDataSize(this));
//Create Mission, Waypoints, Populate Missions Entry WPT ID Field
Utils._AddNewMission(this);
}else{
//...handle null path
}
}
//Deep copies an array
public static function DeepCopy(source:Object):*{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
The if statement validates that pathArr is not null but when the Utils._AddToVirtualFileSystem method is called the method triggers an exception stating that pathArr is null when passed.
All code that affects the class this block resides in is synchronous and to my knowledge it's not been changed elsewhere. The only thing i can think of is that the system is slowing down due to a complex trig/log/algebra background simulation happening for another completely encapsulated class that is cycling at 250ms an iteration.
Could this slowdown be causing the if statement to falsely evaluate?.
Console Output - Without 2 magical traces in:
pathArr:
pathArr:
LastFP: undefined
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at HUD.Components::TrComp/AddToVirtualFileSystem()[C:\Users\***\Desktop\***\***\src\HUD\Components\Scripts\Tr\TrDataLoader.as:221]
at SharedUtils::Utils$/_AddToVirtualFileSystem()
at SharedUtils.Missions::Mission/SaveMission()[C:\Users\***\Desktop\***\***\libs\SharedUtils\Missions\Mission.as:287]
at LoadDialogue/SaveSelectedData()
at LoadDialogue/OKClose()
at TrLibrary_fla::btnOk_46/LeftClick()
at TrLibrary_fla::_ButtonInstance_5/LeftClick()
Console Output - With 2 magic traces in
pathArr:
pathArr: [object Object],[object Object],[object Object],[object Object]
pathArr: [object Object],[object Object],[object Object],[object Object]
pathArr: [object Object],[object Object],[object Object],[object Object]
LastFP: [object Object]
Update:
To add to the annoyance, i added in 2 trace statements to the method that calls this block and magically all is as it should be. Removing both trace statements and it breaks again, but leave one in and remove the other and it works.
Update 2/3:
Added more code before if statement as well as additional trace statements to methods before and after as well as the console outputs. Note, as this is Flash Builder i always perform a full "Clean Build" as I've been bitten before by FB's buggy ass partial builds.
Update 4:
As an array is what is being called and i recall reading something about how AS 3.0 handles arrays i decided to deep copy the array parameter in the call to the SaveMission method and removed the magic trace statements. It works for now (2 test runs) without the magic traces. I'd love to know why though?
instance.trRoot.selMission.SaveMission(selFile,**pathArr**); to instance.trRoot.selMission.SaveMission(selFile,**Utils.DeepCopy(pathArr)**); and works without traces?

Related

AS3 null object error on movie clip 1009 cannot access

Hello I was wandering if someone could help, I keep getting this error spat back at me when I try to launch something in as3. Do I need to import something? Apologies, I originally learned AS2 and I'm now slowly learning AS3.
baby steps.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at draganddropframe1_resetter2_0_fla::MainTimeline/frame3()
at flash.display::Sprite/constructChildren()
at flash.display::Sprite()
at flash.display::MovieClip()
this.window_mc.visible = true;
this.windwo_mc.offwindow.addEventListener(MouseEvent.CLICK, shutwin);
function shutwin(event:MouseEvent):void
{
this.window_mc.visible = false;
}
UPDATES -----------
A method that appears to have worked around it by changing the direct path to 'this'. Clicked inside the movieclip, added a layer called actions and inserted this script that referenced the movieClip I wanted to hide when clicked.
this.addEventListener(MouseEvent.CLICK, fl_ClickToHide);
function fl_ClickToHide(event:MouseEvent):void
{
this.visible = false;
}
The error you are getting means an object, (moveiclip, variable, etc ) doesn't exist.
Go to your publish settings, and check the box that says "permit debugging". Then when you get that error in your output window it will also display the exact line number the error occurred on. That line will probably tell you what object is null.
It looks like you have a typographical error in your second line. This line
this.windwo_mc.offwindow.addEventListener(MouseEvent.CLICK, shutwin);
should be
this.window_mc.offwindow.addEventListener(MouseEvent.CLICK, shutwin);
You've interchanged w and o.
Otherwise, I would suggest doing Ribs's answer.
UPDATES ----------- "from me "
A method that appears to have worked around it by changing the direct path to 'this'. Clicked inside the movieclip, added a layer called actions, and inserted this script that referenced the movieClip I wanted to hide when clicked.
this.addEventListener(MouseEvent.CLICK, fl_ClickToHide);
function fl_ClickToHide(event:MouseEvent):void
{
this.visible = false;
}
Place this script inside the Movie.

illogical remove child error when looking through DisplayObjects, flash AS3

Argument Error #2025:
The supplied DisplayObject is not a child of the caller
In my program I have a structure of display objects representing enemy units on screen, arranged like this:
0: "enemy handler" ➔ [object EnemyHandler]
0: "enemy" ➔ [object Enemy1]
0: "enemy's skin"(MovieClip) ➔ [object EnemySkin1]
0: "skin image" ➔ [object Shape]
The document class contains one instance of EnemyHandler, and it contains multiple instances of Enemy1, Enemy2 ect.. each of these has a skin MovieClip attatched.
The Enemy class (from which Enemy1/2/3 ect inherits) contains a property expired, which is set to true, from within the Enemy class (enemy.update), when the Enemy has reached a certain point.
In the enemy handler class is a function, and is where the problem lays, that loops through an array of all the Enememy display objects, updating there position and then,
if(tempEnemy.expired)
{
tempEnemy.destroy(); // removeChild(skin)
enemyList.splice(tempEnemy);
removeChild(tempEnemy)
}
when run, if all of the enemies reach the end-point in the order in which they were created, there is no problem, however if one for instance travels faster, and reaches the endpoint before, an error #2025 (The supplied DisplayObject is not a child of the caller) is thrown.
I've narrowed it down to the fact that the program attempts to remove the enemy twice, for reasons that i cannot discern. It loops through and removes the desired enemies, then attempts to remove it again, even though it is spliced from the array (which happens correctly, and the first attempt at removeChild is allways succesfull)
It is probably something fairly simple on my behalf, so forgive me, but any help is appreciated. here's the files;
[code on frame]
pastebin.com/vcXzQpr9
[Enemy.as]
pastebin.com/RNXgK8Ex
[EnemyHandler.as]
pastebin.com/6fytxbMW
[Enemy0.as] & [Enemy1.as]
pastebin.com/5bW3Aa0H
[Utils.as]
pastebin.com/PQ2LPV0v
[traceDl.as] {debuggnig the display list}
pastebin.com/9vQGKcYP
Array.splice() takes an integer for the position where you want to start splicing, then how many items you want to remove. So you need to use
enemyList.splice(enemyList.indexOf(tempEnemy), 1);
instead of passing the Enemy instance. It may have appeared to work correctly when the order didn't change, because coercing tempEnemy to int (which splice() will have done automatically) produces a zero, so in your destroyEnemy function it was actually just removing the first item in the list each time.

Detect Exception thrown by a method in referenced DLL (.Net)

I have c#.net code which calls a method from another external/referenced .net assembly. This method I am calling throws an exception if a certain property from the object I am passing it is null. Here it is in a nutshell:
public void Add(string key, object obj)
{
..
//if the Foo property from obj is null then
throw new Exception("Foo property is null or empty")
..
}
In my client code which calls the DLL's Add method, I would like to be able to detect that this particular exception was raised, maybe distinguished by its "Foo property is null or empty" message. Currently, I get a NullReferenceException when it hits this method, so I catch this exception.
Question1:
Can I get the error message associated with the exception being thrown by the code I am calling (in the referenced assembly)??
Question2:
Is this considered bad practice or maybe just atypical?
Obviously, I can disassemble the third-party DLL to discover that my obj I'm passing in must have this "Foo" property set. So, my question here is somewhat for the sake of exercise (and because I'm a n00b).
Catching System.Exception and showing the exceptions Message property is all I needed. At first, I kept getting a NullReferenceException with "Object reference not set to instant of an object" message at the Add method, but I was expecting to get an Exception with the message "Foo property is null or empty" error. Some condition changed in my code and I now get what I expect.

How to correctly Deserialize obects while catching errors

I have a class DataFile which is the top level class that I am serializing. DataFile contains an ArrayCollection which in-turn contains objects which extend ArrayData, each which overrides readExternal in different ways.
Over the course of the development the ArrayData object from version 1.0 is now different than the ArrayData object in version 1.1.
This causes deserialization to fail, most often with a null object error.
This is expected behavior. What I would like to happen is that in cases where an error occurs the object would simply be ignored and we would continue deserialization.
To effect this I have thrown try..catch logic into the deserialization for the ArrayData
override public function readExternal(input:IDataInput):void {
try {
testvalue = input.readObject();
newTestValue = input.readObject(); //a value that is not a part of the file being deserialized
catch(e:Error){
//an error occurred, but just keep going
}
}
I was hoping that this would allow the deserialization chain to continue doing its thing and then would allow me to clean up the broken data after everything has been deserialized.
The problem I am now having is that the serialization of the ArrayCollection fails immediately after an error is caught in a bad ArrayData object with a index out of bounds error.
Error #2006: The supplied index is out
of bounds.
I have tried faking data in the catch portion of te ArrayData object but nothing works. I don't know why the error is bubbling up the deserialization chain and I do not know how to prevent this.
If anyone has any ideas on where I should go next in an attempt to resolve this issue I would appreciate the feedback.
Thanks,
Dan

TypeError: Error #1009 Actionscript 3

I am extremely frustrated. I'm following a tutorial and mimicing it on my own. I have been able to sort out most of the errors so far but this one has me stumped. I have tried replacing all of the class files with the tutorial specimen ones but i still get the error.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.senocular.utils::KeyObject/construct()
at com.senocular.utils::KeyObject()
at com.asgamer.basics1::Ship()
at com.asgamer.basics1::Engine()
Now, not really understanding the error properly I paste dumped the files online for you to look at.
Ship class: textbin.com/78z35
Engine class: textbin.com/32b24
KeyObject class: textbin.com/p2725
As the error still occured when using the specimen class files I really have no idea where to begin. I will gladly try out any suggestions.
Tip: If you allow debugging, the exception will tell you the exact line in the source code where the Error is being thrown. Assuming you're using the Flash IDE, go to publish settings and in the Flash tab check "Permit debugging". This will makes thing much easier for you.
Anyway, you have an error message. If you read it carefully, you can narrow down where the problem is. I don't know if you are a programmer or you have any interest in being one; if you're not, this answer will hopefully solve this particular problem. Anyway, if you don't mind the rambling, let me tell you that if you're interested in becoming a better programmer, paying attention to errors and learning how to debug / troubleshoot problems is one of the most important abilities you need to develop (if not the most important one); so maybe this will give you a few hints you can use to solve other problems as well.
The message says:
Cannot access a property or method of
a null object reference.
This means, at some point, you did something like this:
someobject.someMethod();
or
someobject.someProperty = "foo";
And someobject happened to be null. You can't call methods or access properties of null.
Ok, so now you know, somewhere, a variable had null as its value. Notice that the fact that you define a variable of property doesn't mean it actually holds an object.
This just says that a variable called mySprite can hold an object of the type Sprite:
var mySprite:Sprite;
But until at some point you create a Sprite and assign it to mySprite, the value held by mySprite will be null. If you do:
mySprite.x = 0;
Before initializing mySprite (i.e. before assigning a Sprite to it), you will have this same Null Reference error.
This error message also offers some helpul context, which you can use to your advantage (in them old days... errors in Flash were silent; when things didn't work, you had to manually trace down the problem).
Ok, let's break this error message down:
at com.senocular.utils::KeyObject/construct()
at com.senocular.utils::KeyObject()
at com.asgamer.basics1::Ship()
at com.asgamer.basics1::Engine()
What you have above is called a stack trace. It basically tells you where the code blew up, and also gives you some context: how did you get there.
The first line tells where the error actually occurred. That is, the construct method in the KeyObject object. That method was called from the KeyObject constructor, which was in turn called from the Ship constructor, which was in turn called from the Engine constructor.
Now, let's analyze how you got there, following the stack trace, bottom-up:
Code in Engine constructor:
ourShip = new Ship(stage);
This creates a new Ship object. It passes a reference to the stage to the Ship constructor method.
Code in Ship constructor:
this.stageRef = stageRef;
key = new KeyObject(stageRef);
It grabs the ref passed in the previous step. It stores it and creates a new KeyObject object. The KeyObject constructor is passed a reference to the stage (which is the same ref that was passed from Engine to Ship).
Code in KeyObject constructor:
KeyObject.stage = stage;
keysDown = new Object();
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
Now we got to the point where the error message told you the problem was. So, somewhere, you are using a variable that holds null and trying to access one of its methods or properties.
This KeyObject stores the reference to stage it was passed in a static variable and creates a new Object object. So far, no problems. KeyObject cannot be null (it's a reference to a Class). The second line itself cannot have this null problem either. So, if this is all the code in that method, the problem has to be either in the third or the fourth line. Both access the stage reference you passed and try to call a method (addEventListener) on it. So if one fails, the other will fail as well. Then, the third line: that's where the problem has to be.
So, at that point stage is null. As said previously, you can't call a method on null, and that's what the error is telling you.
Now, if you get back to the first method call, you can see this is the origin of the problem:
ourShip = new Ship(stage);
You can be pretty sure that, at this point, stage was null. Add that to the fact that Engine extends MovieClip (which is in turn a DisplayObject), and to the fact that any DisplayObject has a reference to the stage object only while it's added to the display list. The conclusion: an instance of Engine was not attached to the display list when its constructor was ran.
A way to fix this (there might be others) could be moving the code in the Engine constructor to a separate function that will be executed only if / when the Engine object has a valid reference to the stage object.
public function Engine() : void {
if(stage) {
initialize();
} else {
addEventListener(Event.ADDED_TO_STAGE,initialize);
}
}
private function initialize(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE,initialize);
// here goes the code that's currently in Engine constructor
}
Hope this helps.
I have a feeling your stage property is null.
You have have to test this yourself with a trace of the stage object.
In the first line in the constructor of you Engine class, add:
trace(stage);
Add that just above this line:
ourShip = new Ship(stage);
If it traces "null" then that is your problem.