Я пытаюсь передать произвольные исключения с сервера XMLRPC клиенту (оба скрипта Python, типы исключений определяются с обеих сторон). Там примерная клиентская реализация в ActiveState Recipes, которая анализирует возвращенную "faultString", сравнивает ее со списком известных исключений и, если она найдена, вызывает это исключение (вместо того, чтобы обернуть его в xmlrpclib.Fault
).
Пример ответа на исключение XMLRPC:
<?xml version='1.0'?>
<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value>
<int>1</int>
</value>
</member>
<member>
<name>faultString</name>
<value>
<string>ValueError:</string>
</value>
</member>
</struct>
</value>
</fault>
</methodResponse>
Рецепт ActiveState разбивает строку "ValueError:" и сравнивает "ValueError" с ValueError.__name__
(который находится в allowed_errors = [ValueError, TypeError]
, см. ссылку выше).
Можно ли передавать все исключения вроде этого, т.е. автоматически поднимать любое исключение (полученное из Exception
или какого-либо другого базового класса) на стороне клиента (после того, как оно было поднято на сервере)?
ActiveState script работает, но я не хочу регистрировать каждое исключение, которое может быть выбрано (должно быть в allowed_errors
).
(Бонусный вопрос: есть ли еще одна технология, кроме XMLRPC, которая могла бы правильно справиться с этой проблемой? Pyro?)
Вы можете заполнить список allowed_errors
из __builtins__
:
[exc for exc in __builtins__ if isinstance(exc, BaseException)]
Это будет обрабатывать обычный случай, для встроенных исключений, таких как ValueError
, TypeError
, OSError
и т.д. Возможно, вы можете сделать что-то более продвинутое, например PyYAML и pickle, где они автоматически выслеживают любое связанное исключение отправляется, но это открывает себя для вредоносных атак.
Если вы хотите, чтобы прозрачность клиента/сервера, которая автоматически создавала исключения из сервера на клиенте, подразумевает, что Pyro, вероятно, будет лучшим выбором, чем XML-RPC.