WIL provides a number of facilities for altering its error handling behavior, some automatic and some explicit.
A common usage for these features is to add custom error logging behavior; see the page on error logging and observation for more detailed discussion of those particular usages with examples.
Unless otherwise noted, customizations are intended to be established at module initialization before any WIL functions have been called, and left unchanged for the lifetime of the module. Changing the customization on the fly is likely to result in race conditions.
Unless otherwise noted, the
Set...Callback
functions permit clearing the callback by passing nullptr
,
but you cannot change the callback from one non-null value to another.
(The fact that race conditions can occur if callbacks are changed on the fly
means that this limitation is unlikely to be relevant in practice.)
Custom result logging
void wil::SetResultLoggingCallback(callback);
Sets a callback function that is called whenever WIL logs a failure. The callback function should be declared as follows:
void __stdcall CustomLoggingCallback(wil::FailureInfo const& failure) noexcept;
Debugging information only:
You can check in the debugger whether a custom result logging callback is enabled
by inspecting the variable wil::details::g_pfnLoggingCallback
.
Custom error message generation
void wil::SetResultMessageCallback(callback);
Sets a callback function that is called whenever WIL logs a failure. The callback function should be declared as follows:
void __stdcall CustomResultMessageCallback(
_Inout_ wil::FailureInfo* failure,
_Inout_updates_opt_z_(cchDebugMessage) PWSTR pszDebugMessage,
_Pre_satisfies_(cchDebugMessage > 0) size_t cchDebugMessage) noexcept;
The callback may optionally generate a debug message in
pszDebugMessage
based on the information in failure
.
If callback does not put a message in pszDebugMessage
,
then the default message is used.
Even though the failure
parameter is passed as a non-const pointer,
you must not modify the FailureInfo
.
Debugging information only:
You can check in the debugger whether a custom result logging callback is enabled
by inspecting the variable wil::g_pfnResultLoggingCallback
.
Custom exception types
We recommend that your custom exceptions derive from wil::ResultException
.
If you do that, then the existing WIL library will support your custom exception
automatically.
However, it may be the case that you are using an existing library which throws
its own exceptions, in which case you can teach WIL about those custom exceptions.
void wil::SetResultFromCaughtExceptionCallback(callback)
Sets a callback function that is used to convert an exception
to an HRESULT
.
The callback function should be declared as follows:
HRESULT __stdcall CustomResultFromCaughtException() noexcept;
The custom exception handler is called from inside a catch
block.
The expected pattern is
HRESULT __stdcall CustomResultFromCaughtException() noexcept
{
try
{
throw;
}
catch (custom_exception1 const& ex)
{
return ex.ExtractHResult();
}
catch (custom_exception2 const& ex)
{
return ex.ExtractHResult();
}
catch (...)
{
return S_OK;
}
}
The callback function should return S_OK
for any exceptions
it does not understand,
in which case the exception is treated as an unknown exception.
(See "Custom behavior for unknown exceptions.")
Custom behavior for unrecognized exceptions
See Exception Guards for a description of the exceptions that WIL supports by default. See Custom exception types for information on adding support for your custom exception types.
If an exception goes unrecognized, WIL fails-fast by default, because throwing an unrecognized exception is a programming error, not a runtime error.
bool wil::g_fResultSupportStdException = true;
bool wil::g_fResultFailFastUnknownExceptions = true;
If you don't want WIL to recognize std::exception
, then
set wil::g_fResultSupportStdException
to false
.
If you don't want WIL to fail fast when an unknown exception is detected,
set wil::g_fResultFailFastUnknownExceptions
to false. In that case,
WIL behaves as follows:
- The
HRESULT
for an unrecognized exception isHRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)
. - The debug text is normally empty, but by default, WIL will use the
std::exception::what()
string forstd::exception
-derived classes.
Custom debugger detection
bool(__stdcall *wil::g_pfnIsDebuggerPresent)() noexcept = nullptr;
Set wil::g_pfnIsDebuggerPresent
to a pointer to a function that returns
true
if a debugger is present or false
if not.
If not customized, then WIL uses the system IsDebuggerPresent()
function.
bool wil::g_fIsDebuggerPresent = false;
Records whether WIL believes a debugger is present.
Debugging information only:
You can patch this value to true
in the debugger to retroactively change
the value calculated by g_pfnIsDebuggerPresent
. This is convenient if
debugging a user-mode program from the kernel debugger, because the kernel
debugger is not detected by IsDebuggerPresent()
.
Custom fail-fast behavior
bool (__stdcall *wil::g_pfnWilFailFast)(wil::FailureInfo const& info) noexcept = nullptr;
Set wil::g_pfnWilFailFast
to a pointer to a function that
is called to fail fast.
If the pointer is nullptr
or the function returns,
then WIL generates its own fail-fast exception.
The return value of the function is not used.
Other customizations
bool wil::g_fResultOutputDebugString = true;
Set wil::g_fResultOutputDebugString
to false
to suppress the generation
of failure debug messages to the debugging console.
bool wil::g_fBreakOnFailure = false;
Set wil::g_fBreakOnFailure = true
to call DebugBreak()
(or its customized
replacement) when a failure occurs.
C++/CX support
If compiled in C++/CX mode (MSVC /GW compiler flag),
the WIL error handling library automatically adds support for
thrown Platform::Exception^
exceptions.
You can suppress this behavior by defining the symbol
RESULT_SUPPRESS_STATIC_INITIALIZERS
before including any WIL headers.
Debugging information only:
You can check in the debugger whether C++/CX support
is enabled by inspecting the variables
wil::details::g_pfnResultFromCaughtException_WinRt
,
wil::details::g_pfnResultFromKnownExceptions_WinRt
,
and
wil::details::g_pfnThrowPlatformException
.
They will be null if C++/CX support is disabled
and non-null if C++/CX support is enabled.
If compiled in C++/CX mode,
the WIL THROW_XXX
macros throw Platform::Exception^
objects
by default.
To force them to throw wil::ResultException
,
set
wil::g_fResultThrowPlatformException
to false
.
bool wil::g_fResultThrowPlatformException = true;