Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm writing a D3D11 framework and I'm trying to clean it up a little, and I'm unsure how to handle errors and return codes in my classes/code.

What is the "best" and cleanest way to implement error handling ?

Should I just use the HRESULT and other D3D types as return values for errors and such, or should I create my own types, or should I go with native c/c++ types ?

share|improve this question

2 Answers 2

Misunderstood the question, see the comments.


You basically have three choices:

  • Throw an exception
  • Return an error code and use an out parameter to return the actual value
  • Call an error callback

Exceptions: Very simple to implement, however they might incure a huge performance and/or memory impact, even during normal execution, depending on the compiler. You should run a performance analysis on your target compiler and platform, both in normal execution (i.e. don't actually throw an exception, use only a try/catch), and in exceptional execution. If your program slows down by a large amount after using exceptions, don't use them. However, Joel doesn't like exceptions because they create invisible return paths. Thanks to C++ RIAA (shared_ptr) I don't think that's an issue anymore, your mileage may vary.

Error codes: The upside of error codes are that you can see all code paths in your source code. There are however two problems with them:

  1. You need to check the error code of every call that can fail.
  2. They steal your return code, so you are forced to use an out parameter for your actual return value.

Another upside of this approach is that it is not memory intensive like some exception handling implementations. Also, you still need some CPU time to check the return code of your function calls, however this cost is usually only a fraction of the cost that exception handling incurs. Again, check with your compiler.

Callback: When something goes wrong, you call a callback. This only works if the callback is actually able to fix the problem (i.e. if the game can't allocate any more memory, defragment the heap).

Another approach are assertions, which are useful for testing for "impossible situations". They are usually only enabled if the game is running in a debug environment and are stripped out in a release environment. The assert implementation in assert.h does this automatically, it makes the assert macro do nothing if NDEBUG is defined.

I've taken much information for this answer from the book Game Engine Architecture by Jason Gregory, specifically Chapter 3.3.

share|improve this answer
    
At the moment I'm using error codes, but what I wanted to know was: should I create my own types and error codes, or should I use the types provided by D3D11 ? By doing so my functions can just return HRESULT codes. Or is it better to make build my own on top of D3D ? –  dotminic Sep 2 '11 at 14:55
    
Are you just building a D3D/Windows framework or are you trying to go cross platform? It seems like your framework should handle errors internally to maintain a consistent state and abstract out the specifics to the users of the framework, perhaps string error returns or your own codes like you mention. After all, how are end users supposed to fix errors in your framework? And end users probably only care about things like "out of memory" or "asset data error on load" with queries for deeper information for reporting and log purposes. –  Patrick Hughes Sep 9 '11 at 1:12
    
It's just a D3D/Windows framework, I'm not using any abstractions, and since D3D code already has error codes and functions that allow in depth information and error reporting, i'm unsure as to if it's any valid point to build more on top of that. –  dotminic Sep 10 '11 at 16:50

The HRESULT type is extensible for user application (i.e. is not limited to system applications). Here's the MSDN documentation for it's layout. As long as you set the Customer bit you can use the other 31 bits for whatever you want. So I see no reason to not use HRESULTs. Of course you'll need a function to convert the HRESULT into a string.

That's how most C APIs work, too. Except they use ints instead of HRESULTs. Also, the standard library stores the error code in a global variable errno. This works as long as there is an "invalid" return value for every function, for example a null pointer for functions returning pointers.

You shouldn't invent your own types unless you have to. If you use HRESULTs you can't store things like filenames in the value. For example, if loading a resource file fails, you can't store the filename inside. The solution to this problem is to log the error as soon as you find it, directly in the caller of the resource loading function, and not any further up the call stack.


That's about as clean as it gets.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.