wscalls: handle connection errors (#53900)
This commit is contained in:
parent
d029e24e4c
commit
2ca413d3d3
|
@ -19,6 +19,7 @@ from wcs import fields
|
|||
from wcs.data_sources import NamedDataSource
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.qommon.form import UploadedFile
|
||||
from wcs.qommon.misc import ConnectionError
|
||||
from wcs.wf.attachment import AddAttachmentWorkflowStatusItem
|
||||
from wcs.wf.export_to_model import ExportToModel, transform_to_pdf
|
||||
from wcs.wf.form import FormWorkflowStatusItem, WorkflowFormFieldsFormDef
|
||||
|
@ -1511,6 +1512,48 @@ def test_formdata_named_wscall_in_conditions(http_requests, pub):
|
|||
assert len(http_requests.requests) == 1
|
||||
|
||||
|
||||
def test_formdata_named_wscall_in_comment(pub):
|
||||
create_user(pub)
|
||||
NamedWsCall.wipe()
|
||||
|
||||
wscall = NamedWsCall()
|
||||
wscall.name = 'Hello world'
|
||||
wscall.request = {'url': 'http://remote.example.net/json'}
|
||||
wscall.store()
|
||||
assert wscall.slug == 'hello_world'
|
||||
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.fields = [
|
||||
fields.CommentField(id='0', label='Hello X{{ webservice.hello_world.foo }}Y.', type='comment'),
|
||||
]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
||||
with mock.patch('wcs.qommon.misc._http_request') as mocked_http_request:
|
||||
data = {'foo': 'bar'}
|
||||
mocked_http_request.return_value = (mock.Mock(headers={}), 200, json.dumps(data), 'headers')
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert 'Hello XbarY.' in resp.text
|
||||
|
||||
if pub.loggederror_class:
|
||||
pub.loggederror_class.wipe()
|
||||
with mock.patch('wcs.qommon.misc._http_request') as mocked_http_request:
|
||||
mocked_http_request.side_effect = ConnectionError('...')
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert 'Hello XY.' in resp.text
|
||||
if pub.loggederror_class:
|
||||
assert pub.loggederror_class.count() == 0
|
||||
|
||||
wscall.record_on_errors = True
|
||||
wscall.store()
|
||||
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert 'Hello XY.' in resp.text
|
||||
assert pub.loggederror_class.count() == 1
|
||||
|
||||
|
||||
def test_formdata_evolution_registercommenter_to(pub):
|
||||
user = create_user(pub)
|
||||
|
||||
|
|
|
@ -381,6 +381,7 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
|
|||
post_data=self.post_data,
|
||||
post_formdata=self.post,
|
||||
formdata=formdata,
|
||||
handle_connection_errors=False,
|
||||
)
|
||||
except ConnectionError as e:
|
||||
status = 0
|
||||
|
|
|
@ -24,6 +24,7 @@ from django.utils.encoding import force_text
|
|||
from quixote import get_publisher, get_request
|
||||
|
||||
from wcs.api_utils import MissingSecret, get_secret_and_orig, sign_url
|
||||
from wcs.qommon.errors import ConnectionError
|
||||
from wcs.workflows import WorkflowStatusItem
|
||||
|
||||
from .qommon import _, force_str, misc
|
||||
|
@ -71,6 +72,7 @@ def call_webservice(
|
|||
cache=False,
|
||||
notify_on_errors=False,
|
||||
record_on_errors=False,
|
||||
handle_connection_errors=True,
|
||||
**kwargs,
|
||||
):
|
||||
|
||||
|
@ -142,18 +144,30 @@ def call_webservice(
|
|||
formdata_dict['extra'] = payload
|
||||
payload = formdata_dict
|
||||
|
||||
if method in ('PATCH', 'PUT', 'POST'):
|
||||
if payload:
|
||||
headers['Content-type'] = 'application/json'
|
||||
payload = json.dumps(payload, cls=JSONEncoder)
|
||||
response, status, data, dummy = misc._http_request(url, method=method, body=payload, headers=headers)
|
||||
elif method == 'DELETE':
|
||||
response, status, data, dummy = misc._http_request(url, method='DELETE', headers=headers)
|
||||
else:
|
||||
response, status, data, dummy = misc.http_get_page(url, headers=headers)
|
||||
request = get_request()
|
||||
if cache is True and request and hasattr(request, 'wscalls_cache'):
|
||||
request.wscalls_cache[unsigned_url] = (status, data)
|
||||
try:
|
||||
if method in ('PATCH', 'PUT', 'POST'):
|
||||
if payload:
|
||||
headers['Content-type'] = 'application/json'
|
||||
payload = json.dumps(payload, cls=JSONEncoder)
|
||||
response, status, data, dummy = misc._http_request(
|
||||
url, method=method, body=payload, headers=headers
|
||||
)
|
||||
elif method == 'DELETE':
|
||||
response, status, data, dummy = misc._http_request(url, method='DELETE', headers=headers)
|
||||
else:
|
||||
response, status, data, dummy = misc.http_get_page(url, headers=headers)
|
||||
request = get_request()
|
||||
if cache is True and request and hasattr(request, 'wscalls_cache'):
|
||||
request.wscalls_cache[unsigned_url] = (status, data)
|
||||
except ConnectionError as e:
|
||||
if not handle_connection_errors:
|
||||
raise e
|
||||
if notify_on_errors or record_on_errors:
|
||||
exc_info = sys.exc_info()
|
||||
get_publisher().notify_of_exception(
|
||||
exc_info, context='[WSCALL]', notify=notify_on_errors, record=record_on_errors
|
||||
)
|
||||
return (None, None, None)
|
||||
|
||||
app_error_code = get_app_error_code(response, data, 'json')
|
||||
|
||||
|
|
Loading…
Reference in New Issue