Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

clabinsky

How do you handle errors?

This topic is 6019 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been experimenting a lot with errors but I have to admit that I have not checked C++ throw, try and catch so I might be totally out in deep water. Goal: An error handling class that records errors in a logfile. The reporting should be such that I know in which class the error occured and specifically in which function && statement. My simple solution: I have a class CError that is a Singleton, globally accessible. Each class has #inludes "CError.h" and has a private member: CError *cErr; that is initiated at startup like so: CError *cErr=CError::getInstance(); I only want to know errors here so the logging will only be done when a call does not result in what I want. That is for example
        
    HRESULT hr;
    hr=call some directx function;
    if(FAILED(hr))
       //I usually have two choices return NULL or bool

       //For bool

       return cErr->Log("<classname>:<functionname>:<description>",<hr optional1>,<bool: return value>);
      //For NULL

      {
        cErr->Log("<classname>:<functionname>:<description>",<hr optional1>);
        return NULL;
      }
  

The Error class overloads the Log function many times and can be called with different results.

1. It returns the value that is specified in <bool: return value>
2. If no parameter is specified it returns nothing
3. If hr is included, it looks up the hr message in a table and adds it to the logfile.

Here is a real function using the Errorhandler:
      
//Logs Error and HRESULT and returns nothing   

hr=m_lpDirectDraw->CreateSurface(ddDesc,&lpPrimary,NULL);
if(FAILED(hr))
{
     cErr->Log("CSurfBase:CreateSurface: Call to CreateSurface failed",hr);
     return NULL;
}

//Logs Error and hr and returns false

hr=m_lpDirectDraw->RestoreAllSurfaces();
if(FAILED(hr))
     return cErr->Log("CSurfBase:RestoreSurfaces: call to RestoreAllSurf..failed",hr,false);
        
Now it also takes care of repeated messages and records how many times the error occured like so: **********Above message was repeated 218 times*************** The handler can also be turned off and will then only return a value. I know it is an extra function call but hey, something went wrong so who cares. Now give me your devastating comments on why this is not good, cause I have the feeling it is not. I´ll use this during development cause it is easy to remove if needed. I am actually a Swede, living in paradise. EDIT: sigh, why do I always mess this up... Edited by - clabinsky on December 30, 2001 1:01:46 AM Edited by - clabinsky on December 30, 2001 1:03:28 AM Edited by - clabinsky on December 30, 2001 1:05:41 AM

Share this post


Link to post
Share on other sites
Advertisement
I use asserts. I think that halting your app where you encounter the error is useful. Also, this saves time in development and if done correctly ensures that just about nothing goes wrong in release.

I''m sure many would disagree but I think crashing your game at every error ensures that they get the attention that every bug requires.

Share this post


Link to post
Share on other sites
To tell you the truth, I started out without any handler and spent hours hunting simple bugs. This might be a sluggish way to log the errors but it is really easy and it works great so far.

On every hour of coding I now spend max 10 minutes tracking errors - it was the opposite before.

Hope to see lots of ideas from you guys.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
i saw some game use setjmp and longjmp to handle error.....

Share this post


Link to post
Share on other sites
I personaly use try,catch,throw and assert. I only use assert to validate pointers tho. I use try catch and throw for everything else.

FYI u can have throw pass on a struction to catch...


-----------------------------------------------------------
"People who usualy use the word pedantic usualy are pedantic!"-me

Share this post


Link to post
Share on other sites
I use asserts to validate function parameters and such. I use bool return values for normal errors, and one try/catch block in the main loop of my program to catch exceptional errors (fatal errors).

I thought about using try/catch for every normal error handling but I still think it's a bad idea. You'll pay a small performance hit not only for every error thrown, but also for every try block your program enters. Also, in every catch you need to check if the error is a normal error and the program can continue, or if it's a fatal error and the program needs to stop, in which case you rethrow the error. That error checking must be in every single catch in your program, unless you decide to create a different exception classes for every error possible, in which case you just catch the errors you want to catch, but that could mean dozens of catch clauses for one try, and hundereds of exception classes overall.

Another problem with throwing an error is you need to be absolutely certain that a person wants to catch that error. In the program at my company I remember reading a section of code where the programmer wanted to add a new record in our database but they wanted to make sure the record didn't already exist, and because the program throws an exception when an empty recordset is return, the code looked something like this:

    
ShipOrder ship_order;

try
{
// Query the database to be certain no previous shipping orders for this order number exist

ship_order.GenerateOrderNumberFilter(new_order_number);
AfxMessageBox("Error, blah, blah, blah");
}
catch(DBM_NO_RECORD_EXCEPTION)
{
ship_order.AddNew(new_order_number);
}


Notice how they were required to catch the DBM_NO_RECORD_EXCEPTION when they didn't want to catch that error. If they hadn't caught an error they didn't want to, then a previous try/catch would catch it and report it as an error. So now the error handling is in the try clause and the normal code flow is in the catch. IMO, that's a very good reason why try/catch should only be used for fatal errors.


- Houdini

Edited by - Houdini on December 30, 2001 10:52:44 AM

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!