This depends on if that is an error or an expected behavior.
Unexpected Errors
When you expect the property has to exist, you directly access it.
container[propertyName]
If the situation does not match your assumption Python will raise an error. The default behavior is to exit all functions until someone catches the error. When the error is not caught Python performs the default error handling (printing the stack trace + error message to console). At that stage the execution stack is emptied and no further processing will happen within Python. In a Python application the application would end, in the BGE the execution of your Python controller ends for this individual frame).
Expected Errors
When you know that errors can happen, but they are no expected behavior, you can implement your own custom error handler, that brings your process flow back to track.
For example: You expect a property “targetName” to contains the name of a game object.
Your code
- reads the property value,
- searches for an object of that name,
- assigns the result to a trackTo actuator,
- activates the actuator
When the property does not exist your code can skip the further steps but the actuator should be activated regardless of the result.
It could be like this:
try:
targetName = container["targetName"]
target = scene.objects[targetName]
actuator.object = target
except KeyError:
pass # do nothing
controller.activate(actuator)
Be aware this deals with an expected KeyError. It does not matter what statement causes the error. It can be anywhere between try and except. It does not deal with unexpected errors such as AttributeError unless you explicitly mention that in the code.
Alternative Processing
If you expect the property may exist or maybe not you need to deal with the situation that it is present as well as that it is not present. The non existing property is a valid situation - not a error situation.
When both situations need the same processing you simply use the same code:
count = container.get("count", 0)
sendMessage("count value", count)
[/count]
This is not always possible especially when the used statements cause Errors by themselves (such as dictionary access). In this case you can perform a pre-check:
if "count in container:
count = container[“count”]
else:
count = 0
When each situation needs a different processing you need a pre-check to separate the process flow:
if “count” in container:
count = 0
container[“count”] = count
sendMessage(“new count”, count)
else:
count = container[“count”]
sendMessage(“current count”, count)
print(“Count:”, count)
Remarks:
Be aware checking each possible situation results in a lot of validation code. This is inefficient, hard to read and hard to maintain. It can quickly happen, that the same check will be performed several times (code replications, process replication).
Therefore it is necessary to think about what your code expects, and how what situations it can manage. It is really no problem to use the default error handling when something unexpected happens during your tests. You might want to review your design and/or turn the unexpected error into an expected error.
I hope it helps a bit.