Reputation: 26495
We are working on a system in perl that has to communicate with multiple web services that provide SOAP endpoints to work with. They provide WSDL files to describe the services (in C# .Net, "Add Service Reference" would use these). We use wsdl2perl.pl to import these files into perl modules.
All is working, except for when the services return a fault.
We call a service like this:
my $service = OurInterfaces::OurService::OurPort->new();
my $result = $service->ourMethod({ someParameter => '1234' });
die $result->get_faultstring()->serialize() if not $result;
When we try to access the fault string, our perl script dies with this:
<Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>Error deserializing message: Cannot resolve class for Fault/detail/Errors/ErrorDetail via UPSRateTypemaps::RateService at /usr/lib/perl5/site_perl/5.8.8/SOAP/WSDL/Expat/MessageParser.pm line 147.
at line 1 at /usr/lib/perl5/site_perl/5.8.8/SOAP/WSDL/Expat/Base.pm line 82
.
Message was:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soapenv:Body><soapenv:Fault><faultcode>Client</faultcode><faultstring>An exception has been raised as a result of client data.</faultstring><detail><err:Errors xmlns:err="http://www.ups.com/schema/xpci/1.0/error"><err:ErrorDetail><err:Severity>Hard</err:Severity><err:PrimaryErrorCode><err:Code>10001</err:Code><err:Description>The XML document is not well formed</err:Description><err:Digest>&lt;/RateRequest> does not close tag &lt;Request>.</err:Digest></err:PrimaryErrorCode><err:Location/></err:ErrorDetail></err:Errors></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope></faultstring><faultactor>urn:localhost</faultactor></Fault>
It appears that the XML being returned for faults isn't mapped to a class (Class::Std) properly. How can we fix this?
Also is there any articles out there describing what we need to do to map the error messages? For the most part wsdl2perl.pl is just plain magic to us.
Upvotes: 3
Views: 2290
Reputation: 26495
Since no answers yet. I'll post what we did to get it working.
We opened up the Typemap.pm
file that has our $typemap_1
, and added lines like this:
'Fault/detail' => 'UPSTrackElements::Errors'
'Fault/detail/Errors' => 'UPSTrackElements::Errors',
'Fault/detail/Errors/ErrorDetail' => 'UPSTrackTypes::ErrorDetailType',
...
wsdl2perl.pl imported the error classes we needed, but it didn't hook them up properly in the typemap file. In general, we had to append 'Fault/detail' to the front of where it mapped all of our Error classes. I'm not sure why wsdl2perl.pl couldn't map them right, when it obviously had no issue generating the classes.
We had to fill out the appropriate XPath for every single field in the fault xml. It is working for us now, but was rather ugly to figure out.
Upvotes: 2