Click here to Skip to main content
11,572,828 members (64,557 online)
Click here to Skip to main content

HRESULT Error Check Simplifier

, 12 Jun 2011 CPOL 64.6K 468 33
Rate this:
Please Sign up or sign in to vote.
Exception based error check that automates the FAILED() comparison.

Introduction

It is boring to have to write a lot of ifs only to check for failures. At the same time, it is important to take care of every error that can happen in the code. The class described in this article just makes it easy to throw an exception every time a failure is returned from another function. This way you can do only what you have to do in the code and unify error handling.

With a little help from my colleagues from CP, here is an updated version with some traits for a no-throw version, and a new method to show a textual version for the HRESULT error:

template<bool ThrowException>
struct HResultChecker
{
    static void Check(HRESULT hr);
};

template<> struct HResultChecker<false>
{
    static void Check(HRESULT hr) 
    {
        hr;
    }
};

template<> struct HResultChecker<true>
{
    static void Check(HRESULT hr)
    { 
        if( FAILED(hr) ) 
            AtlThrow(hr);
    }
};


/**
* Use this class instead HRESULT in order to the assignement operator be 
* tested. In case of failure, the funcion AtlThrow() will be called.
*
* @sa AtlThrow(), CAtlException.
*/
template<bool ThrowException>
class HResultT
{
public:
    /// Test the HRESULT in the constructor.
    HResultT(HRESULT hr = S_OK)    { Assign(hr); }

    /// Test failure of the received hr. If FAILED(hr), the function 
    /// AtlThrow() will be called.
    HResultT &operator = (HRESULT hr)
    {
        Assign(hr);
        return *this;
    }

    /** 
    * Retrieves the error desription of the HRESULT member.
    * @return string message for the HRESULT.
    *
    * @author ddarko (comment from CodeProject)
    * @date 2005-09
    */
    LPCTSTR ErrorMessage()
    {
        // a lot of code
    }

    /// Extractor of the stored HRESULT.
    operator HRESULT () { return m_hr; }

private:
    void Assign(HRESULT hr) // throw( CAtlException )
    {
        HResultChecker<ThrowException>::Check(m_hr = hr);
    }

    HRESULT m_hr; // the stored HRESULT
    std::basic_string<TCHAR> m_desc; // error description
};

/// Throw exception version.
typedef HResultT<true> HResult;

// No-Throw exception version.
typedef HResultT<false> HResultSafe;

Using the code

The use is very straightforward. You can catch the exceptions inside the function or pass it to the callee:

/**
Using HResult inside the funcion
*/
void function()
{
   HResult hr;

   try
   {
      hr = MakeSomething();
      hr = MakeSomethingElse();
      hr = MakeTheFinalSomething();
   }
   catch(CAtlException& e)
   {
      cout << "wow! Error " << e.m_hr << ": " << e.ErrorMessage() << "\n";
   }
}

/**
Using HResult bypassing the exception
*/
void Class::Method() throw ( CAtlException )
{
   HResult hr = MakeSomething();
   hr = MakeSomethingElse();
   hr = MakeTheFinalSomething();
}

Points of interest

Maybe before using the class above, you would to like to learn about CAtlException, AtlThrow(), and FormatMessage(). Very interesting stuff for exception based error handling.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Wanderley Caloni
Software Developer (Senior) Intelitrader
Brazil Brazil
Capacitation
15 years experience in Windows operating systems developing in information security companies;
great team relationship; problem solving using systemic vision, knowledge bases maintenance,
chronograms and people coordination.

Technical historic
Software and hardware inventory
Clipboard and PrintScreen protection using windows hooks and global messages manipulation
Driver writing system event log
DeviceIoControl user/kernel communication
Desktop remote control using VNC technique
Remote execution tool PsExec (SysInternals) like
Print control using regex (Boost) and shell hook
Access policies management during user logon/logoff (register and hooks)
Datgabase migration CTree -> SQL (OLE classes)
Windows authentication using custom GINA and DCOM; Credential Provider (Vista)
CTree database synchronism using custom DCOM service
Bootable Linux CD with bash scripts and disk cryptography tools using C language
Hard disk encryption and PenDrive (USB) storage control
Blue Screen analysis using memory dumps and WinDbg live (Gflags)
System account execution using custom COM service
MBR (Master Boot Record) customization library
Blowfish/SHA-1 encryption library using C++ and 16 bits Assembly
Log access driver using shared memory between user and kernel mode
Kernel mode API hook for 9X and NT platforms
16 bits Assembly loader; debugging using debug.com tool
Executable protection using embedded domain authentication recorded inside files resources
Internet Explorer 6/7 and Firefox 1/2 browsing protection using Assembly 32 bits code injection
Code, strings and execution protection library (using Win32 interruptions)
Centralized log generation library using shared memory and global events
Internet Explorer 6/7 BHO (Broser Helper Object) and ActiveX; Mozilla/Firefox XPI plugin
Projects management using Source Safe, Bazaar and Batch (Win) scripts
Kernel mode debugging using SoftIce and WinDbg for NT

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 5 Pin
KarstenK20-Nov-13 0:25
memberKarstenK20-Nov-13 0:25 
GeneralMy vote of 5 Pin
OAlpha28-Sep-13 15:25
memberOAlpha28-Sep-13 15:25 
GeneralRe: My vote of 5 Pin
Wanderley Caloni20-Apr-15 2:49
memberWanderley Caloni20-Apr-15 2:49 
GeneralTrait classes for exception vs. manual check. Pin
CoffeeBuzz3-May-08 6:40
memberCoffeeBuzz3-May-08 6:40 
GeneralRe: Trait classes for exception vs. manual check. Pin
Wanderley Caloni5-May-08 1:18
memberWanderley Caloni5-May-08 1:18 
GeneralRe: Trait classes for exception vs. manual check. Pin
Yiannis Spyridakis11-Jun-11 7:12
memberYiannis Spyridakis11-Jun-11 7:12 
GeneralRe: Trait classes for exception vs. manual check. Pin
Wanderley Caloni12-Jun-11 9:19
memberWanderley Caloni12-Jun-11 9:19 
GeneralRe: Trait classes for exception vs. manual check. Pin
Yiannis Spyridakis13-Jun-11 2:27
memberYiannis Spyridakis13-Jun-11 2:27 
GeneralError description Pin
Darko@Hot5-Mar-07 3:40
memberDarko@Hot5-Mar-07 3:40 
GeneralRe: Error description Pin
Wanderley Caloni5-Mar-07 6:05
memberWanderley Caloni5-Mar-07 6:05 
GeneralRe: Error description Pin
Darko@Hot5-Mar-07 6:46
memberDarko@Hot5-Mar-07 6:46 
GeneralDid you know the trick ... Pin
Stephan Pilz19-Sep-05 2:29
memberStephan Pilz19-Sep-05 2:29 
GeneralRe: Did you know the trick ... Pin
Wanderley Caloni19-Sep-05 3:39
memberWanderley Caloni19-Sep-05 3:39 
Generalit works but not perfect Pin
HeartFriend18-Sep-05 15:46
memberHeartFriend18-Sep-05 15:46 
GeneralRe: it works but not perfect Pin
Wanderley Caloni18-Sep-05 17:33
memberWanderley Caloni18-Sep-05 17:33 
GeneralRe: it works but not perfect Pin
Wanderley Caloni18-Sep-05 18:03
memberWanderley Caloni18-Sep-05 18:03 

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 | Terms of Use | Mobile
Web04 | 2.8.150624.2 | Last Updated 12 Jun 2011
Article Copyright 2005 by Wanderley Caloni
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid