Jump to content
Sign in to follow this  
CarlGustaffa

Exception handling

Recommended Posts

Hi

I have the following little exception handling test for try, throw, and catch:

[] spawn {
waitUntil {player == player};
myvecs = [1,2];
for "_i" from 0 to (count myvecs + 1) do {
	//myvecs may change due to being modified in other scripts.
	try {
		if (_i > count myvecs) then {
			throw "select out of bounds";
		} else {
			_vec = myvecs select _i;
			hint str (myvecs select _i);
		};
	} catch {
		if (_exception == "select out of bounds") then {
			hint "exception sucessfully catched";
		};
	};
	sleep 0.5;
};
};

and something weird struck me. I now no longer get a "division by zero" error when using count to count myvecs. In debug console I get the following:

myvecs select 0 - 1

myvecs select 1 - 2

myvecs select 2 - <null> this should have generated an error, right?

myvecs select 3 - <null> and only now do I get the expected error message.

Did anything change?

Oh, and what a weird example, mixing blocks with sqs and use of commands not available to us (echo). Also, what is the real purpose of this kind of exception handling? A normal if then else structure would be able to do the exact same thing. Especially considering the note: ArmA scripting commands do not create an exception by themselves if they encounter an illegal situation (i.e. you can't use the here described exception handling for error trapping.)

Share this post


Link to post
Share on other sites

Why should it give an error for 2:

...
if (_i > count myvecs) then {
    throw "select out of bounds";
}
...

You _i values are 0,1,2,3 and there is 2 elements. You do a greater-than comparison, thus it is only thrown on 3.

Also, what is the real purpose of this kind of exception handling?

Exception handling is often used for "serious" errors or errors you do not know how to handle where they arise.

For example if you attempt to get the position of an object that does not exists you get [0,0,0] (This might be wrong, I may be thinking of setPos'ing nil, but just play along). That value is useless, how can I distinguish between bad input or some object that in fact is at [0,0,0] (this will most likely be some object created by scripting). As mentioned on the link, Arma scripting commands, do not generate exceptions, which is also why they are not very useful with Arma, only user created scripts. For exceptions to really be useful, the base/standard library (here the builtin Arma commands) have to use them (and I think this is true for any language).

However, image you have some script files with a lot of functions. Let's say A is rather low level. B builds higher level functions on A, and C does the same for B. Let's say we have some function in A, say getPos. If that function get's bad input it doesn't know what to do. It is just a general scripting functions. However, C might know what to do since this is some high-level spawning script. Then someone who makes A can throw an exception on bad input instead of returning [0,0,0]. The high-level spawning script can then handle this and decide what to do:

//This is in the module C - the spawning script.
try {
   //Get some data
   _vehiclePos = [My_Data] call B_GetVehiclePos; //This then calls some function in module A.
}
catch {
   if (_exception == "NO_OBJECT") then {
      //OK it doesn't exist then create this.
       _veh = "MyClass" createVehicle My_Data;
       My_Data = SOME_COMMANDS _veh;
       //Now get the data
       _vehiclePos = [My_Data] call B_GetVehiclePos;
   };
};

Obviously you can do the same with if-then, however, the reason why you got nil, for example, get's lost during the calls. And you can't be sure about values like [0,0,0].

Edited by Muzzleflash

Share this post


Link to post
Share on other sites

Sorry, don't think I explained it well enough. During testing of the exception I didn't get the expected results. So I checked with the debugger and got startled. Without the script, try this in Gaia's debug:

myarray = [0,1]; //rewrote numbers to 0,1 to avoid confusion.

myarray select 0 generates 0.

myarray select 1 generates 1.

myarray select 2 generates <null> but no error message.

myarray select 3 generates the error message.

So, why the <null> without error? The expected result would be an error message, since [0,1] select 2 isn't possible, only select 0 and select 1.

Or try the following init.sqf:

[] spawn {
myarray = [0,1];
sleep 1;
player globalChat format ["select 0: %1", myarray select 0];
sleep 1;
player globalChat format ["select 1: %1", myarray select 1];
sleep 1;
player globalChat format ["select 2: %1", myarray select 2];
sleep 1;
player globalChat format ["select 3: %1", myarray select 3];
};

For me this generates:

Select 0: 0

Select 1: 1

Select 2: <null> (without any error message).

Select 3: <null> (this time WITH an error message).

I would expect an error message also on Select 2. What is it that I'm not getting? Lol :)

Share this post


Link to post
Share on other sites

ive encountered in the past that 1 out of bounds does not generate error, 2 out of bounds does.

maybe its a fail safe implemented to cater to the select 0 being nr 1 instead of select 1...

Share this post


Link to post
Share on other sites

So, why the <null> without error? The expected result would be an error message, since [0,1] select 2 isn't possible, only select 0 and select 1.

As mentioned on the link you gave - the commands available to you do NOT use the exception systems and do not give you any errors:

Note: ArmA scripting commands do not create an exception by themselves if they encounter an illegal situation (i.e. you can't use the here described exception handling for error trapping.)

Okay so Arma does give you real errors just bad values like NULL. None of the builtin commands uses throw, therefore you cannot catch anything from the commands available.

What about your own script. Well yes you use throw:

if (_i > count myvecs) then {
throw "select out of bounds";
}

That means you can catch it whenever it is larger than the items in your array which is 2. That means when _i is 3 or larger you throw an exception and catches it.

TL;DR - Arma doesn't throw exceptions in any of it's commands.

Nevermind thought this thread was about exceptions and not "errors" - anyone have info on whether they actually are linked as suggested.

Maybe the interpreter is written in C and they use a null value to mark the end of the array.

However, since the Arma commands do not throw exceptions anyway, you can not rely on that anyway, as you can see.

Edited by Muzzleflash

Share this post


Link to post
Share on other sites

I'm starting to think that myself - null marks the end but is not counted. So in my own example, it means that I can't trust blindly for testing weather or not I get an actual error message or not.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×