soap: activer api_error=True sur Parsifal (#73411) #37

Closed
nroche wants to merge 3 commits from wip/73411-maelis-manage-soap-error into main
4 changed files with 71 additions and 6 deletions

View File

@ -32,6 +32,7 @@ from passerelle.base.models import BaseResource, HTTPResource
from passerelle.utils.api import endpoint
from passerelle.utils.conversion import simplify
from passerelle.utils.jsonresponse import APIError
from passerelle.utils.soap import SOAPError
from passerelle.utils.templates import render_to_string
from . import activity_schemas, family_schemas, invoice_schemas, schemas, utils
@ -68,15 +69,16 @@ class ToulouseMaelis(BaseResource, HTTPResource):
wsdl_name = wsdl_short_name + 'Service?wsdl'
wsdl_url = urljoin(self.base_wsdl_url, wsdl_name)
settings = zeep.Settings(strict=False, xsd_ignore_sequence_order=True)
return self.soap_client(wsdl_url=wsdl_url, wsse=wsse, settings=settings)
return self.soap_client(wsdl_url=wsdl_url, wsse=wsse, settings=settings, api_error=True)
def call(self, wsdl_short_name, service, **kwargs):
client = self.get_client(wsdl_short_name)
method = getattr(client.service, service)
try:
return method(**kwargs)
except zeep.exceptions.Fault as e:
raise APIError(e.message, err_code='%s-%s-%s' % (wsdl_short_name, service, e.code))
except SOAPError as e:
e.err_code = '%s-%s-%s' % (wsdl_short_name, service, e.data['soap_fault']['code'])
raise
def check_status(self):
assert self.call('Family', 'isWSRunning')

View File

@ -16,6 +16,7 @@
from urllib import parse as urlparse
from lxml import etree
from requests import RequestException
from zeep import Client
from zeep.cache import InMemoryCache
@ -48,10 +49,13 @@ class SOAPFault(SOAPError):
log_error = False
def __init__(self, client, fault):
dico = fault.__dict__
if isinstance(dico.get('detail'), etree._Element):
dico['detail'] = etree.tostring(dico['detail']).decode()
super().__init__(
f'SOAP service at {client.wsdl.location} returned an error "{fault.message or fault.code}"',
data={
'soap_fault': fault.__dict__,
'soap_fault': dico,
},
)

View File

@ -0,0 +1,14 @@
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>E19 : La voie est obligatoire</faultstring>
<detail>
<ns1:MaelisSiteException xmlns:ns1="site.ws.maelis.sigec.com">
<message xmlns:ns2="site.ws.maelis.sigec.com">E19 : La voie est obligatoire</message>
<code xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="site.ws.maelis.sigec.com" xsi:nil="true"/>
</ns1:MaelisSiteException>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>

View File

@ -192,6 +192,15 @@ def test_call_with_wrong_credentials(family_service, con):
'err': 1,
'log_error': False,
'http_status': 200,
'data': {
'soap_fault': {
'message': 'The security token could not be authenticated or authorized',
'code': 'ns1:FailedAuthentication',
'actor': None,
'detail': None,
'subcodes': None,
},
},
'err_code': 'Family-isWSRunning-ns1:FailedAuthentication',
}
@ -3659,7 +3668,10 @@ def test_add_rl1_direct_debit_order_soap_error(family_service, invoice_service,
Link.objects.create(resource=con, family_id='1312', name_id='local')
resp = app.post_json(url + '?NameID=local', params=params)
assert resp.json['err'] == 'Invoice-addDirectDebitOrder-soap:Server'
assert resp.json['err_desc'] == "E520 : La REGIE CS [{0}] n''existe pas dans la base Maelis"
assert (
resp.json['err_desc']
== 'SOAP service at https://example.org/InvoiceService?wsdl returned an error "E520 : La REGIE CS [{0}] n\'\'existe pas dans la base Maelis"'
)
def test_get_rl1_direct_debit_order(family_service, invoice_service, con, app):
@ -3735,7 +3747,10 @@ def test_get_rl1_direct_debit_order_soap_error(family_service, invoice_service,
Link.objects.create(resource=con, family_id='1312', name_id='local')
resp = app.get(url + '?NameID=local', params=params)
assert resp.json['err'] == 'Invoice-getDirectDebitOrder-soap:Server'
assert resp.json['err_desc'] == "E520 : La REGIE CS [{0}] n''existe pas dans la base Maelis"
assert (
resp.json['err_desc']
== 'SOAP service at https://example.org/InvoiceService?wsdl returned an error "E520 : La REGIE CS [{0}] n\'\'existe pas dans la base Maelis"'
)
def test_read_school_year_list(con, app):
@ -4413,6 +4428,36 @@ def test_read_school_list_address_and_level(site_service, con, app):
assert 'text' in item
def test_read_school_list_address_and_level_soap_error(site_service, con, app):
site_service.add_soap_response(
'readSchoolForAdressAndLevel',
get_xml_file('R_read_school_for_adress_and_level_soap_error.xml'),
status=500,
)
url = get_endpoint('read-schools-for-address-and-level')
resp = app.get(url, params={'id_street': '', 'num': '', 'year': ''})
assert resp.json['err'] == 'Site-readSchoolForAdressAndLevel-soap:Server'
assert (
resp.json['err_desc']
== 'SOAP service at https://example.org/SiteService?wsdl returned an error "E19 : La voie est obligatoire"'
)
assert resp.json['data'] == {
'soap_fault': {
'message': 'E19 : La voie est obligatoire',
'code': 'soap:Server',
'actor': None,
'detail': '<detail xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'
+ '\n <ns1:MaelisSiteException xmlns:ns1="site.ws.maelis.sigec.com">'
+ '\n <message xmlns:ns2="site.ws.maelis.sigec.com">E19 : La voie est obligatoire</message>'
+ '\n <code xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
+ ' xmlns:ns2="site.ws.maelis.sigec.com" xsi:nil="true"/>'
+ '\n </ns1:MaelisSiteException>\n </detail>'
+ '\n ',
'subcodes': None,
}
}
def test_read_school_list_child_and_level(family_service, con, app):
family_service.add_soap_response(
'readSchoolForChildAndLevel', get_xml_file('R_read_school_for_child_and_level.xml')