= Error handling in Orxonox = Whenever something unwanted happens, the programmer needs to react in a certain way.[[br]] 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 [[br]] == 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 [wiki:doc/Output] for more information. [[br]] '''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! [[br]] For information about how to use them, see [wiki:doc/Exception Exceptions]. [[br]] 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. [[br]] 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. [[br]][[br]] 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. [[br]] 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 ;) [[br]][[br]] 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. [[br]][[br]] The more asserts you insert, the easier bug tracking will be. You might even spot them before they could ever be triggered. [[br]][[br]] '''Important: Asserts are only useful when the mistake is in the program. Throwing asserts for bad input doesn't help anyone, use exceptions then! [[br]] 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. [[br]] The example above would then read: {{{ void fooBar(myClass* ptr) { ... OrxAssert(ptr != 0, "You screwed the wrong pointer!"); ptr->aMemberFunction(); } }}}