Reputation: 10183
The Spyne manual points out that the right way to create SOAP Faults with Spyne is to raise instances of spyne.model.fault.Fault
(or your own subclass):
@add_metaclass(ComplexModelMeta)
class Fault(ComplexModelBase, Exception):
# ...
I'm trying to understand why it subclasses ComplexModelBase
. My initial assumption was that I declare the elements I want to go into the SOAP Fault's <detail>
element in my Fault
subclass, like so:
class MyApplicationError(Fault):
__namespace__ = 'http://myapplication.com/ns'
_type_info = [
('reason', Unicode),
]
However, when actually raising this exception, it looks like I have to pass a plain dict into the detail
parameter of the constructor.
What is the best practice for filling the detail
with a structured set of data? Do I even declare this structure in my Fault
subclass?
If yes, how do I fill it? If not, why does Fault
subclass ComplexModelBase
?
Upvotes: 2
Views: 1264
Reputation: 8001
Fault(detail={'foo': {'bar': 123}})
will serialize to:
<ns0:Fault xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>soap11env:Server</faultcode>
<faultstring>Fault</faultstring>
<faultactor></faultactor>
<detail>
<foo>
<bar>123</bar>
</foo>
</detail>
</ns0:Fault>
You can write a new constructor for Fault
in a subclass to make it easier to generate the details dict. E.g.:
class SuperFault(Fault):
def __init__(self, foo, bar):
super(SuperFault, self).__init__('Server.SuperFault', 'E001234',
detail={'SuperFault': {'foo': foo, 'bar': bar}})
Please note that due to some stupid limitation, the length of the dict passed to detail must be 1. Please file an issue if that's a problem for you.
Upvotes: 2