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

  1. Read the embedded FailureInfo (hr, message, origin file/line) from the ResultException to identify the failing API call.
  2. Fix the underlying Win32/COM failure the HRESULT reports (permissions, path, handle validity, COM registration).
  3. 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.
  4. 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

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


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)