Skip to content

ThrowIfFailed

Chuck Walbourn edited this page Dec 4, 2015 · 32 revisions

When programming COM APIs like Direct3D, it is important to always check the HRESULT return value for success or failure. This can be done using the SUCCEEDED or FAILED macros, but can get tedious when making lots of calls

Not all Direct3D functions return HRESULT. Many of them return void because they can't fail, fail silently, or the failure will be reported on the next Present.

For "modern" Direct3D programming, the recommended solution is to throw a C++ exception on a failed HRESULT. The C++ DirectX templates for universal Windows apps, Windows 8 Store, Windows phone 8, Xbox One, and the Direct3D Win32 Game templates all make use of the DX::ThrowIfFailed helper.

#include <exception>

namespace DX
{
    inline void ThrowIfFailed(HRESULT hr)
    {
        if (FAILED(hr))
        {
            // Set a breakpoint on this line to catch DirectX API errors
            throw std::exception();
        }
    }
}

The usage is very simple.

DX::ThrowIfFailed( device->CreateTexture2D(&depthStencilDesc,
    nullptr, &depthStencil) );

DX::ThrowIfFailed should be used whenever a failure is fatal and should result in 'fast-fail' of the application. Otherwise, traditional if FAILED(hr) or if SUCCEEDED(hr) patterns should be used to handle failures that the application can handle.

The legacy DXUT framework makes use of macros like V and V_RETURN as a pattern for dealing with HRESULT values, but these make assumptions about the surrounding functions.

Enhancements

The templates all include the basic implementation above, but production use might want to make use of a slightly improved version as follows:

#include <exception>

namespace DX
{
    // Helper class for COM exceptions
    class com_exception : public std::exception
    {
    public:
        com_exception(HRESULT hr) : result(hr) {}

        virtual const char* what() const override
        {
            static char s_str[64] = { 0 };
            sprintf_s(s_str, "Failure with HRESULT of %08X", result);
            return s_str;
        }

    private:
        HRESULT result;
    };

    // Helper utility converts D3D API failures into exceptions.
    inline void ThrowIfFailed(HRESULT hr)
    {
        if (FAILED(hr))
        {
            throw com_exception(hr);
        }
    }
}

Further reading

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Windows 8.1
  • Xbox One

Architecture

  • x86
  • x64
  • ARM64

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v18
  • MinGW 12.2, 13.2
  • CMake 3.20

Related Projects

DirectX Tool Kit for DirectX 12

DirectXMesh

DirectXTex

DirectXMath

Win2D

Tools

Test Suite

Model Viewer

Content Exporter

DxCapsViewer

Clone this wiki locally