'How to throw an std::system_error exception from a FAILED(HRESULT)?
This is how to throw ordinary Win32 errors correctly, automatically retrieving the error description, and it works marvellously well:
if (!SomeWinFunc()) {
throw std::system_error(GetLastError(),
std::system_category(),
"SomeWinFunc crashed badly");
}
However, I'm uncertain on how to deal with COM errors, which are checked idiomatically like this:
HRESULT hr = comObj->SomeFunc();
if (FAILED(hr)) {
throw std::system_error(hr, // <-- is it correct here?
std::system_category(),
"SomeFunc crashed right now");
}
Is it correct to pass an HRESULT to system_error, or there is another way to throw exceptions from a COM function?
Solution 1:[1]
Typically, I handle this using the Microsoft standard _com_error exception type, which can be easily raised by one of the following.
_com_util::CheckError(hr); // throws when FAILED(hr)
_com_issue_error(hr); // throws always
A Win32 error can be converted to an HRESULT like so:
hr = HRESULT_FROM_WIN32(GetLastError());
However, this means that you have to deal with a new exception type, which may be problematic. To do this the pure STL way, I think you need to derive a new error_category and use that instead of system_category. I would look at the <system_error> header and copy the implementation of system_category, updating as necessary for HRESULTs.
Ideally, the different facility codes in the HRESULT would be served by different error_category implementations -- doing so would very effectively communicate the exception and its source. But that is tricky, and you can probably get away with a single com_category that deals with HRESULTs generically.
Solution 2:[2]
This article has a great walkthrough of how to define an std::error_code for COM API errors: https://kb.firedaemon.com/support/solutions/articles/4000121648-fitting-com-into-c-system-error-handling
The gist of it is to just use _com_error to get the message, and the rest is mostly std boilerplate for creating error_codes.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Michael Gunter |
| Solution 2 | MHebes |
