简体   繁体   中英

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?

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 HRESULT s.

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 HRESULT s generically.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM