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


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

Для традиционных программистов 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, что произошла ошибка.

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