Вот простая версия RPC-сервера / клиентской библиотеки:
Server:
try
receive message
deserialize arguments
invoke appropriate method
serialize result
transmit result
catch any Exeption
serialize Exception
transmit Exception
Client (Library code, not the caller):
try
serialize arguments
make remote call
receive "something"
deserialize "something" (could be serialized exception or result)
catch Timeout,Network,Other exceptions not from server
handle whatever the library handles
if deserialized "something" is an exception
rethrow exception from server for caller to catch
else, good/expected results
return results
Итак, если вы хотите, чтобы исключения были перехвачены вызывающим абонентом, они, возможно, отличаются от обычных исключений тем, что они должны быть сериализованы и переданы по сети для повторного вызова для вызывающего абонента.
Абоненту не нужно делать ничего особенного, если существует клиентская библиотека. Если клиентская библиотека не существует, то вызывающая сторона должна также взять на себя роль клиентской библиотеки. Это означает, что вызывающая сторона должна различать сериализованные результаты и сериализованные исключения (в этот момент программист, вероятно, в любом случае реализует специальную версию кода клиентской библиотеки просто для того, чтобы избежать появления уродливого кода вызывающей стороны).
Очевидно, что вы не можете просто использовать сигнатуры типов для различения исключений и результатов (в противном случае, что произойдет, если тип возвращаемого значения и типы исключений для метода RPC были одинаковыми?). Так что в коде сериализации есть небольшая нагрузка для сервера, чтобы пометить разные ответы.