Click here to Skip to main content
Click here to Skip to main content
Go to top

Neat HRESULT to exception converter

, 21 Oct 2005
Rate this:
Please Sign up or sign in to vote.
A clean and easy way to convert an HRESULT error to an exception including file name and line number.

Introduction

I've got this idea as an expansion to HRESULT Error Check Simplifier By Wanderley Caloni, so I guess his introduction would be better than if I wrote one. Many thanks to Wanderley Caloni for writing the article.

I'll just introduce here what I have added. The article mentioned above, has a class that checks if an HRESULT value is SUCCEEDED or not. If not, it throws an exception. What is added is some extra functionality, to be able to show a message box, with the line number and file name and a custom error message.

Using the code

Take a look at this usage example:

if( NULL == ( direct3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
    throw MyException(_E("Can't create Direct3D object"));
        
hrToException(_E("Can't get adapter display mode")) = 
  direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&Mode);

The throw MyException(_E("Can't create Direct3D object")); is normal and is known to any C++ developer, it only throws an exception.

But the idea is in the next example hrToException(_E("Can't get adapter display mode")) = direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&Mode);: it simply means that if the return HRESULT value from the function call direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&Mode) is FAILED, then throw an exception with the current line number and the current file name and containing the error string "Can't get adapter display mode".

The old way to do this was:

if(FAILED(direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&Mode))
    throw MyException("Can't get adapter display mode",__FILE__,__LINE__);

Imagine your code with this kind of ifs all over the file Smile | :) . At least the new class removes the branching logic off your shoulder.

Here's the _E() macro. It just adds the line number and the file name to the parameter of the exception constructor, to save some typing.

#define _E(str) str##,##__FILE__##,##__LINE__

Your code should be in a try-catch block.

#define _MYTRY        try {

There is a pre-defined catch block, to produce the message box, and also to save some typing. You might change the error[] length if you plan to use longer error strings.

// the catch statement that shows the message box
#define _MYCATCH        \
}                        \
catch(MyException ex)    \
{                        \
    char error[255];    \
    sprintf(error,"%s ( HRESULT = %i ), file: %s, line: %i"  , 
            ex.error_str , ex.hr , ex.file , ex.lineNumber);\
    ::MessageBox(hWnd,error , "MyException Caught" , MB_OK);    \
    exit(E_FAIL);    \
}

The exception class holds only these four pieces of information.

// the exception class
struct MyException
{
    ...

    char* error_str;
    char* file;
    int lineNumber;
    HRESULT hr;
};

Check the line:

hrToException(_E("Can't get adapter display mode")) = 
   direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&Mode);

It is done like this:

// the class that throws, if an HRESULT failed
class HResultToException 
{
public:
    HResultToException& operator()(char* error, 
               char* file_name,int line_number)
    {
        error_str = error;
        this->file_name    = file_name;
        this->line_number = line_number;
        return *this; 
    }

    void operator=(HRESULT hr)
    {
        if(FAILED(hr))
            throw MyException(error_str,hr,file_name,line_number);
    }
};

Conclusion

This article is only to show some ideas to enhance readability, but it lacks reusability. I would appreciate if someone can make it more reusable. Anyway, the article is meant to show an example, that the reader is not supposed to use directly. The reader is supposed to catch the idea and re-implement it as it fits him/her the best.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

I started computing at the age of 11, but first programming experience at age of 15. now i have been programming for 4 years.
 
I have expericenced C/C++, java, pascal, SQL, assembly(8086,386), C#, DirectX, jsp, asp.net, 3dsMax, Maya, Paintshop, Photoshop, javaScript, HTML. Some of the programs i did was Chess( AI ), Tic-tac-toe ( AI ), Minesweeper. I am interested in the field of Mathematics, and AI so much. If i wasn't a programmer i would like to be a mathematician !
 
My dream is to live in a lab, in which i can do whatever research i want. My best hobby is to gain knowledge, and of course trying to produce it Smile | :) .

Comments and Discussions

 
JokeUnderscore macros PinmemberKirit Sælensminde6-Jun-06 18:06 
GeneralA Slightly More Readable Method PinmemberZac Howland25-Oct-05 5:55 
GeneralThe macro _E() PinmemberWanderley Caloni25-Oct-05 2:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140905.1 | Last Updated 21 Oct 2005
Article Copyright 2005 by Mohammad Nabil H.
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid