[ODE] Using exceptions to catch errors

Shamyl Zakariya shamyl at zakariya.net
Wed Aug 11 08:08:56 MST 2004


All

I've tuned my usage of ODE well enough by this point that it *almost* 
never ends up exploding... but of course, once in a blue moon, now and 
then, it does.

Since the default implementation of the error handler calls abort() or 
error(1) my program, obviously, terminates. To the user it looks like 
it crashed! I'd prefer behavior to be to close the simulation, reset 
everything, and show an alert dialog explaining everything.

I know that in principle I could just remove the exit & abort code from 
ODE, but I'd like to use a standard ODE distribution.

So I thought that what I'd do is register my own error handler and have 
it throw an exception, which would be caught and my program would close 
the simulation and reset ODE.

So, here are my error/debug callback functions, where scError and 
scDebug are just vanilla C++ objects.

	void scErrorHandler(int errnum, const char *msg, va_list ap)
	{
		printMessage( errnum, "PANSISim : ODE Error : ", msg, ap );
		throw scError();
	}

	void scDebugHandler(int errnum, const char *msg, va_list ap)
	{
		printMessage( errnum, "PANSISim : ODE INTERNAL ERROR : ", msg, ap );
		throw scDebug();
	}

They're registered with ODE as such:

	dSetErrorHandler( scErrorHandler );
	dSetDebugHandler( scDebugHandler );

And the relevant part of my stepping function looks like this:

	if ( !_aborted )
	{

		try {

			Element::stepAll();

			dSpaceCollide (_space, (void *) this, &nearCallback);
			dWorldStep( _world, timestep() );
			dJointGroupEmpty( _contactGroup );
		}

		catch ( scError err )
		{
			printf( "SimulationCore::step()\tCaught error. aborting stepper\n" );
			_aborted = true;
		}

		catch( scDebug debug )
		{
			printf( "SimulationCore::step()\tCaught debug. aborting stepper\n" );
			_aborted = true;
		}
				
		if ( _aborted )
		{
			stopPANSI(); 	//synchronously stops AI runtime thread
			reset();		//unloads simulation and closes ODE
		}
	}


So, the trouble as I see it is this: in ODE's error.cpp the function 
dError is defined as such:

extern "C" void dError (int num, const char *msg, ...)
{
   va_list ap;
   va_start (ap,msg);
   if (error_function) error_function (num,msg,ap);
   else printMessage (num,"ODE Error",msg,ap);
   exit (1);
}

Where error_function is called, then printMessage, then exit, is 
called. The oddity here is that even though my error callbacks are 
being called and the exception *is* being thrown, exit() is still being 
called. I would have expected that the throwing/catching of an 
exception would have prevented exit from ever being called. Am I 
misunderstanding exception usage? I used to use them all the time in 
java, but I've never used them much in C++, due to poor support.

If it helps the platform is mac OS 10.3 with gcc 3.3

shamyl zakariya | fodder for aggressive meta-lampoonery



More information about the ODE mailing list