-
Notifications
You must be signed in to change notification settings - Fork 513
ThrowIfFailed
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 returnvoid
because they can't fail, fail silently, or the failure will be reported on the nextPresent
.
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 recover from (i.e. are not fatal).
DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D(&depthStencilDesc,
nullptr, &depthStencil));
If you want to handle a specific HRESULT, then you might do something like:
HRESULT hr = m_d3dDevice->CreateTexture2D(&depthStencilDesc,
nullptr, &depthStencil);
if (hr == E_INVALIDARG)
{
// Do something here in response to this specific error.
}
DX::ThrowIfFailed(hr);
For a case where you want to do the error-handling for an HRESULT yourself, be sure to use the SUCCEEDED
or FAILED
macro:
HRESULT hr = m_d3dDevice->CreateTexture2D(&depthStencilDesc,
nullptr, &depthStencil);
if (FAILED(hr))
// Error handling
The legacy DXUT framework makes use of macros like
V
andV_RETURN
as a pattern for dealing withHRESULT
values, but these make assumptions about the surrounding functions and are really only suited to samples development.
The ThrowIfFailed
helper is not part of the DirectX Tool Kit; it's declared in some global header in your application. 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--you'll typically find it declared in the pch.h
header.
#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 templates all include the basic implementation above, but production use might want to utilize a slightly improved version as follows (which are included in the DeviceResources variants of the Direct3D Win32 Game templates).
#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",
static_cast<unsigned int>(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);
}
}
}
All content and source code for this package are subject to the terms of the MIT License.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.
- Universal Windows Platform apps
- Windows desktop apps
- Windows 11
- Windows 10
- Windows 8.1
- Xbox One
- x86
- x64
- ARM64
- Visual Studio 2022
- Visual Studio 2019 (16.11)
- clang/LLVM v12 - v18
- MinGW 12.2, 13.2
- CMake 3.20