Exception handling – Talk

From Bohemia Interactive Community
Jump to navigation Jump to search

Can the if statement handle numbers? Because emptyPositions returns a number and not a boolean. --T_D 20:07, 22 July 2006 (CEST)

IMHO every number larger than zero means true. --Djura 20:38, 22 July 2006 (CEST)


I don't understand what is the point of this structure if you have to throw exceptions only by yourself? You can create same functionality without using it. --MessiahUA 12:06, 30 August 2007 (CEST)

firebomb.sqs example



Probably is this possible too:

[] fireBomb.sqs

_car = _this select 0
if (crew _car == 0) then {
    throw "vehicle empty"
} else {
    if (3 < random 10) then {
        throw "bomb failed"
    } else {
        _car setDammage 1
        if (alive Guba) then {
            throw "bastard still alive"
        }
    }
}       
try {
    TitleText ["Sgt. Detritus: I get bomb to his car ;-)", "PLAIN DOWN"]
    [jeepOne] exec "fireBomb.sqs"
    TitleText ["Sgt. Detritus: He is dead!", "PLAIN DOWN"]
}
catch { if (_exception == "vehicle empty") then { TitleText ["Sgt. Detritus: He have luck, but next time I'll kill him!", "PLAIN DOWN"] } else { TitleText ["Sgt. Detritus: Some strange error appears... " + _exception + "... hmm... another time I'll get him!", "PLAIN DOWN"] }

The first if in the 'firebomb.sqs example is incorrect. you are using a || = conditional OR here, so the code throw "vehicle empty" will be executed if one of the conditions returns true. your intention was to get this code exectued when there is nobody in the vehicle, so you should use && = conditional AND. Additionaly, this code is unnecessary. a simple (crew vehicle == 0) would be much more effective. --TeRp 20:40, 22 July 2006 (CEST)

You are right. I didn't know about crew command. --Djura 20:48, 22 July 2006 (CEST)
There are several reasons the above code won't work.
First of all, exec launches scripts asynchronously, like spawn does. This gives 2 problems. One is that it may enter the "he is dead" part before the bomb script does its first line. Another is that an exception will not (and should not) "unwind" beyond such a boundary; meaning that the script will generate an error as it has gone through all the scopes to the point the spawn/exec command was run without finding a try/catch to match.
Using something like {call compile preprocessfile "firebomb.sqf"} would avoid those problems, though it might be preferrable to inline them (as opposed to putting it in a file of its own) in this particular case.
Another problem is that the exception handler (catch block) is a catch(anything) (as ofpscript forces it to be) but the handler assumes it to be a string. {if typename _exception != "STRING" throw _exception} as the first command in the handler should properly rethrow the exception so it can be handled even further out. ArmAScript has a tendency to toss out errors when you compare strings to non-strings.
Moving to a less technical problem: The exception handling is used as a way of returning values. Exceptions should be used exclusively for runtime handling of error conditions. At least traditionally (I don't really know how this is in ArmAscript, but i suspect this holds true), this was so because exceptions are rather "expensive" in use. Either way, keeping away from this style of scripting also makes the resulting scripts more maintainable.
Exceptions are most useful when different people work on interacting pieces of code. The clue is that the one who detects the error may not know how the caller code needs the error handled. This is especially true of "library code" which is called from multiple places, perhaps by many users in lots of different missions/addons.
--MaHuJa 07:29, 23 August 2006 (CEST) -- Updated MaHuJa 10:04, 16 July 2007 (CEST)