ramensoftware/windhawk · error · ResultException
throw ResultException(failure)
Error message
throw ResultException(failure)
What it means
ThrowResultExceptionInternal is WIL's (Windows Implementation Library) mechanism for converting a failure HRESULT captured in a FailureInfo into a C++ ResultException. When a WIL macro (RETURN_IF_FAILED, THROW_IF_FAILED, etc.) observes a failing HRESULT, WIL's failure machinery lands here and throws ResultException(failure), carrying the HRESULT, message, and origin. It is how WIL surfaces any Windows API failure as a catchable C++ exception.
Solutions
- Read the embedded FailureInfo (hr, message, origin file/line) from the ResultException to identify the failing API call.
- Fix the underlying Win32/COM failure the HRESULT reports (permissions, path, handle validity, COM registration).
- Wrap WI-macro-heavy code in try/catch (const wil::ResultException&) or switch those call sites to RETURN_*/CHECK_* fail-fast variants if exceptions are unwanted.
- Verify debug-string/telemetry capture (wil::SetResultLoggingCallback) so failures are visible with full context.
Example fix
// before
THROW_IF_FAILED(OpenSomeResource(&handle));
// after
try
{
THROW_IF_FAILED(OpenSomeResource(&handle));
}
catch (const wil::ResultException& e)
{
LOG(HRESULT_FROM_WIN32(e.GetFailureInfo().hr));
return e.GetFailureInfo().hr;
} Defensive patterns
Strategy: try-catch
Try / catch
try
{
/* WIL macro calls */
}
catch (const wil::ResultException& e)
{
const auto& info = e.GetFailureInfo();
LOG("WIL failure hr=0x%08X at %s:%u", info.hr, info.pszFile, info.uLineNumber);
} Prevention
- Check return values/preconditions (ACLs, paths, handle validity) before Win32/COM calls wrapped in THROW_/RETURN_ macros.
- Use wil::SetResultLoggingCallback so failures are logged with full FailureInfo context.
- Prefer fail-fast (RETURN_*/WI_VERIFY) variants in code paths where exceptions cannot be handled.
When it happens
Trigger: Any WI enforcement macro in fast-fail/exception mode hitting a failure: THROW_IF_FAILED(...) / RETURN_IF_FAILED(...) wrapping a Win32 or COM call that returned a failure HRESULT, or wil::ResultException rethrown by ResultFromCaughtExceptionInternal when a caught exception is re-normalized.
Common situations: A Win32/COM API fails at runtime (access denied, file not found, RPC failure) inside code built with WIL result macros and WIL_ENABLE_EXCEPTIONS; callers without a try/catch around the WI macro see an unhandled ResultException.
Related errors
- ATL exception: HRESULT 0x
- throw PortableSettingsException(error)
- Failed to start the global hooking session
- Missing path value
- Missing RegistryKey value
AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12).
Data as JSON: /api/errors/773657484e7df31f.
Report an issue: GitHub.
Appendix: source
Thrown at src/windhawk/shared/libraries/wil/result_macros.h:3931
#if !defined(RESULT_SUPPRESS_STATIC_INITIALIZERS)
WI_HEADER_INITIALIZATION_FUNCTION(InitializeWinRt, [] {
g_pfnResultFromCaughtException_WinRt = ResultFromCaughtException_WinRt;
g_pfnResultFromKnownExceptions_WinRt = ResultFromKnownExceptions_WinRt;
g_pfnThrowPlatformException = ThrowPlatformException;
return 1;
});
#endif
#endif
// clang-format on
inline void __stdcall Rethrow()
{
throw;
}
inline void __stdcall ThrowResultExceptionInternal(const FailureInfo& failure)
{
throw ResultException(failure);
}
__declspec(noinline) inline ResultStatus __stdcall ResultFromCaughtExceptionInternal(
_Out_writes_opt_(debugStringChars) PWSTR debugString,
_When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars,
_Out_ bool* isNormalized) WI_NOEXCEPT
{
if (debugString)
{
*debugString = L'\0';
}
*isNormalized = false;
if (details::g_pfnResultFromCaughtException_CppWinRt != nullptr)
{
const auto hr = details::g_pfnResultFromCaughtException_CppWinRt(debugString, debugStringChars, isNormalized);
if (FAILED(hr))
{View on GitHub (pinned to 61d99ed8e1)