Click here to Skip to main content
Click here to Skip to main content

HRESULT Error Check Simplifier

, 12 Jun 2011
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
Web Developer Caloni Tecnology
Brazil Brazil
Capacitation
Ten 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
etc
Follow on   Twitter   Google+

Comments and Discussions

 
GeneralMy vote of 5 PinmemberKarstenK20-Nov-13 0:25 
GeneralMy vote of 5 PinmemberOAlpha28-Sep-13 15:25 
GeneralTrait classes for exception vs. manual check. PinmemberCoffeeBuzz3-May-08 6:40 
GeneralRe: Trait classes for exception vs. manual check. PinmemberWanderley Caloni5-May-08 1:18 
GeneralRe: Trait classes for exception vs. manual check. PinmemberYiannis Spyridakis11-Jun-11 7:12 
GeneralRe: Trait classes for exception vs. manual check. PinmemberWanderley Caloni12-Jun-11 9:19 
GeneralRe: Trait classes for exception vs. manual check. PinmemberYiannis Spyridakis13-Jun-11 2:27 
GeneralError description PinmemberDarko@Hot5-Mar-07 3:40 
GeneralRe: Error description PinmemberWanderley Caloni5-Mar-07 6:05 
GeneralRe: Error description PinmemberDarko@Hot5-Mar-07 6:46 
GeneralDid you know the trick ... PinmemberStephan Pilz19-Sep-05 2:29 
GeneralRe: Did you know the trick ... PinmemberWanderley Caloni19-Sep-05 3:39 
Generalit works but not perfect PinmemberHeartFriend18-Sep-05 15:46 
GeneralRe: it works but not perfect PinmemberWanderley Caloni18-Sep-05 17:33 
GeneralRe: it works but not perfect PinmemberWanderley 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 | Mobile
Web03 | 2.8.140827.1 | Last Updated 12 Jun 2011
Article Copyright 2005 by Wanderley Caloni
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid