Planet
navihomeaboutscreenshotsdownloaddevelopmentforum

Error handling in Orxonox

Whenever something unwanted happens, the programmer needs to react in a certain way.
We support three different ways to handle such situations:

  • Display a message in the console, shell and log
  • Throw an exception that can be caught
  • Abort the program with a message


orxout(#), displays messages

Whenever you want to show the user or the programmer a message, use orxout(#) where # is the level of your output. See Output for more information.

Note: A simple message with level user_error (or internal_error) doesn't trigger an exception or anything yet

Exceptions

This kind of error handling method is used when the programmer has to handle situations that could go wrong, but shouldn't. Mind the difference to Assertions below!
For information about how to use them, see Exceptions.
A good example for exceptions would be a script compiler. Whenever it encounters bad tokens, it throws an exception with a message. The function calling the parser can then catch that exception, display it and act accordingly.
We also use Exceptions when loading a level. If one occurs, we can abort and the user can choose another level. Of course this shouldn't happen, but nobody's perfect.

Keep in mind that you yourself have to display the exception message at the right spot (they do get displayed automatically in level 4 however).

Assertions

Last but not least: Assertions. This is very handy programmer's tool. It helps a lot tracking bugs and sets up a newly created class much quicker.
When should you use it? Basically, an assertion is used when the programmers assumes that a certain condition is true and that otherwise the program would fail somewhere. In short: Whenever something should never go wrong and can't in the eyes of the programmer. But it mostly will ;)

An example: In a function, you receive a pointer and do something like ptr->aMemberFunction() while assuming that ptr != 0 because otherwise, you'll probably get a segmentation fault.

void fooBar(myClass* ptr)
{
    ...
    ptr->aMemberFunction();
}

You can now insert a call to the 'asser()' macro so that whenever ptr == 0 the program aborts. Now this doesn't sound very helpful, but it is: First of all, the abort message tells you exactly where the error has happened (file, line, function). Secondly, the program would have aborted anyway because of the null pointer.

The more asserts you insert, the easier bug tracking will be. You might even spot them before they could ever be triggered.

Important: Asserts are only useful when the mistake is in the program. Throwing asserts for bad input doesn't help anyone, use exceptions then!

Usage: 'assert(condition you assume);' or when you want to tell more use 'OrxAssert(condition, message)'. The message gets then displayed via orxout(user_error) before the assert() macro is called.
The example above would then read:

void fooBar(myClass* ptr)
{
    ...
    OrxAssert(ptr != 0, "You screwed the wrong pointer!");
    ptr->aMemberFunction();
}