I’m using tinyxml to parse xml files, and I’ve found that error handling here lends itself to arrow code. Our error handling is simply reporting a message to a file.
Here is an example:
const TiXmlElement *objectType = dataRoot->FirstChildElement( "game_object" );
if ( objectType ) {
do {
const char *path = objectType->Attribute( "path" );
if ( path ) {
const TiXmlElement *instance = objectType->FirstChildElement( "instance" );
if ( instance ) {
do {
int x, y = 0;
instance->QueryIntAttribute( "x", &x );
instance->QueryIntAttribute( "y", &y );
if ( x >= 0 && y >= 0 ) {
AddGameObject( new GameObject( path, x, y ));
} else {
LogErr( "Tile location negative for GameObject in state file." );
return false;
}
} while ( instance = instance->NextSiblingElement( "instance" ));
} else {
LogErr( "No instances specified for GameObject in state file." );
return false;
}
} else {
LogErr( "No path specified for GameObject in state file." );
return false;
}
} while ( objectType = objectType->NextSiblingElement( "game_object" ));
} else {
LogErr( "No game_object specified in <game_objects>. Thus, not necessary." );
return false;
}
return true;
I’m not huffing and puffing over it, but if anyone can think of a cleaner way to accomplish this it would be appreciated.
P.S. Exceptions not an option.
Edit:
Would something like this be preferable?
if ( !path ) {
// Handle error, return false
}
// Continue
This eliminates the arrow code, but the arrow code kind of puts all of the error logging on one place.
Using return values as error codes just leads to such code, it can’t be improved much. A slightly cleaner way would use
gototo group all error handling into a single block and to decrease the nesting of blocks.This does however not solve the actual problem, which is using return values as error codes. In C, there is no alternative, but in C++ exceptions are available and should be used. If they are not an option, you’re are stuck with what you have.