Обработка ошибок в COM (COM)

Почти все функции COM и методы интерфейса возвращают значение типа HRESULT. HRESULT (имя можно считать как "результирующий дескриптор") — это способ возврата успешного, предупреждения или значения ошибки. HRESULT на самом деле не является дескриптором (см. Почему HRESULT начинается с H, когда это не дескриптор?); это просто значение с несколькими полями, закодированными в него. Согласно спецификации COM, результат нуля указывает на успешность, а ненулевой результат указывает на сбой.

Important

Всегда проверяйте возвращаемые значения HRESULT. Никогда не игнорируйте возвращаемое значение функции COM. FAILED() SUCCEEDED() Используйте макросы (определенные в <winerror.h>) — не сравнивайте напрямую с S_OKкодами успешности, кроме S_OK существующих (например, S_FALSE):

// ✅ Correct — handles all failure codes
HRESULT hr = pStream->Read(buffer, cbSize, &cbRead);
if (FAILED(hr)) {
    // Handle error
    return hr;
}

// ❌ Wrong — misses failure codes that aren't E_FAIL
if (hr == E_FAIL) { ... }

// ❌ Wrong — S_FALSE is success but != S_OK
if (hr != S_OK) { /* this fires for S_FALSE too */ }

Современные вспомогательные средства обработки ошибок:

  • THROW_IF_FAILED(hr)библиотеки реализации Windows (wil) вызывают исключение C++ при сбое
  • winrt::check_hresult(hr) — эквивалент C++/WinRT, вызывает winrt::hresult_error
  • LOG_IF_FAILED(hr) — уил макрос, который регистрируется при сбое, но продолжает выполнение

На уровне исходного кода все значения ошибок состоят из трех частей, разделенных подчеркиванием. Первая часть — это префикс, определяющий объект, связанный с ошибкой, вторая часть — E для ошибки, а третья — строка, описывающая фактическое условие. Например, STG_E_MEDIUMFULL возвращается, если на жестком диске нет места. Префикс stG указывает хранилище, E указывает, что код состояния представляет ошибку, а MEDIUMFULL предоставляет конкретные сведения об ошибке. Многие значения, которые может потребоваться вернуть из метода интерфейса или функции, определяются в Winerror.h.

Дополнительные сведения об обработке ошибок см. в следующих разделах:

коды ошибок COM