Поделиться через


Указание ошибок по исключениям

Для традиционных программистов C ошибки обычно возвращаются с помощью возвращаемых значений или специального параметра [out], возвращающего код ошибки. Это приводит к реализации интерфейсов следующим образом:

long sample(...)
{
    ...
    p = new Cbar(...);
    if (p == NULL)
    {
        // cleanup
        ...
        return ERROR_OUTOFMEMORY;
    }
}

Проблема с этим подходом заключается в том, что возвращаемые значения RPC являются просто длинными целыми числами. Они не имеют особого значения в качестве ошибок (обратите внимание, что error_status_t не имеет специальной семантики на стороне сервера), что имеет важные последствия.

Во-первых, RPC не оповещается о сбое операции; он пытается отменить все аргументы [in, out] и [out]. Семантика сбоев дескрипторов контекста также отличается. Пакет, возвращенный клиенту, по сути, является пакетом успешного выполнения, с кодом ошибки, похороненным глубоко в пакете. Это также означает, что RPC не использует расширенные сведения об ошибках, поэтому клиентское программное обеспечение часто не может определить, где произошел сбой вызова.

Указание ошибок в подпрограммах сервера RPC путем вызова исключений структурированной обработки исключений (SEH) (не C++) является гораздо более лучшим подходом. При возникновении исключения SEH управление переходит непосредственно к времени выполнения RPC. Иногда ошибка возникает глубоко в подпрограмме, которая не может правильно очиститься, и она должна указать ошибку вызывающему объекту. Подпрограмма должна возвращать ошибку вызывающей стороне, что, в свою очередь, может возвращать ошибку вызывающей стороне и т. д. Однако последняя подпрограмма сервера в стеке должна вызывать исключение, прежде чем он возвращается в RPC, чтобы указать RPC, что произошла ошибка.

обработка исключений