Sign in to follow this  
Skute

Error Checking / Handling

Recommended Posts

Skute    134
Whats the best method of error checking and handling when dealing with DirectX? Originally i thought about using exceptions, but decided against them in the end because you need a try/catch everywhere, you dont want a stray exception being thrown and not caught in a game! The other 2 options ive got are, using HRESULTS as return values for all functions, or, using booleans (and possibly having a global error state, which i can check if needed). And then logging all errors manually (i would prefer a more automatic way of reporting errors though...) Ive gone for the later option at the moment, but im not 100% about my code layout, i dont know if there is a better way:
bool CEngineVideo::ValidateVideo(void)
{
	bool bReturn = false;
	HRESULT hrResult = 0;

	hrResult = m_pDevice->TestCooperativeLevel();		// Test the current state of the device
	if (FAILED(hrResult))
	{
		// If the device is lost then return failure
		if (hrResult == D3DERR_DEVICELOST)
			LOGERROR("The device is lost");
		// If the device is not ready to be reset then attempt to do so
		else if (hrResult == D3DERR_DEVICENOTRESET)
		{
			// Reset the device
			hrResult = m_pDevice->Reset(&m_SavedPresentParams);
			if (FAILED(hrResult))
				LOGERROR("Could not reset the device");

			m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 0.0f, 0);
			bReturn = this->RestoreVideo();
		}
	}

	return bReturn;
}

Share this post


Link to post
Share on other sites
Trip99    577
I wrap all the DX calls with a function CheckHr which does a check on the result, if it fails it outputs using the DX error string functions to the output pane and if enabled also to a log file. This makes life easier. Microsoft in their samples use a macro V to do a similar thing but it requires a HRESULT be declared first and hence I find it a bit clumsy. I would also normally return true / false from my own functions rather than reuse DX return codes.

Share this post


Link to post
Share on other sites
dave    2187
If you have a dedicated error handling class or something, then you could write a macro that accepts 2 parameters. The macro could write an call the function, check teh return value and write an error to the dedicated handler.

#define CallWatchError( a, b ) HRESULT err;err = a;ErrHandler.ReportError(b);

For example a would equalt the function call, and b would represent the error string describing the error that would be written to the handler.

So to use it you could do this:

CallWatchError( device->SetTexture( blah ), "Error setting texture" );

the code written by the macro would be like:

HRESULT err;

err = device->SetTexture( blah );
ErrHandler.ReportError( "Error setting texture" );


Warning this isnt a bonafide way of solving the problem, or getting it more automoated but it works.

ace

Share this post


Link to post
Share on other sites
Muhammad Haggag    1358
Quote:
Original post by Skute
Whats the best method of error checking and handling when dealing with DirectX? Originally i thought about using exceptions, but decided against them in the end because you need a try/catch everywhere, you dont want a stray exception being thrown and not caught in a game!

There's no difference between a stray exception not being caught and a return value that has not been checked. In fact, preventing "hidden" errors with exception handling is much easier than with return-value checking, quite simply because a single try catch block wrapping your main loop will prevent stray exceptions, while with return values you'll have to check for every function call.

However, wrapping your main loop with try-catch alone is bad practice. You should do this to avoid uncaught exceptions, and to catch fatal exceptions, on which you log them and exit gracefully. Added to that, you should place an exception handler at the lowest-level you can handle and/or recover from an error. Basically, if a function X throws an exception, the handler should be the nearest function (near to the top of the stack trace) that can possibly recover from the error (meaning: It has enough information to do something about it).

Quote:
The other 2 options ive got are, using HRESULTS as return values for all functions, or, using booleans (and possibly having a global error state, which i can check if needed). And then logging all errors manually (i would prefer a more automatic way of reporting errors though...)

Checking return values would work, but it's very tedious, and often leads to missing some functions.

Having a global error state is ugly, but would work unless you use multi-threading, in which case you'd want to be careful. Also, with a global error state you'd have to be careful with your error propagation so that you don't overwrite the error state. Finally, using booleans + global state doesn't buy you much, because already you're checking HRESULTs using a boolean FAILED/SUCCEEDED macro.

The system I used, when I used to code DirectX applications in C++, was similar to that used by Rich Thomson in his rt library, which can be found here. Basically, you create macros that map HRESULTs to exceptions. In practice this is very clean and works very well. With some additional template wizardry, you might get it to do mapping to specific exception types automatically, but that's just a bonus [smile]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this