From a857805e00421157fb40d3b40fd2ed284328c42d Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Sat, 12 Jan 2019 13:48:56 +0100 Subject: [PATCH] jsonresponse: use string conversion on exceptions (fixes #29060) - introduce exception_to_text(): - first try to use unicode/str on exception - then try to use repr, - finally only render class name and e.args (if present) --- passerelle/utils/jsonresponse.py | 25 ++++++++++++++++++++++++- tests/test_base_adresse.py | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/passerelle/utils/jsonresponse.py b/passerelle/utils/jsonresponse.py index 6dfb50a..2be4f98 100644 --- a/passerelle/utils/jsonresponse.py +++ b/passerelle/utils/jsonresponse.py @@ -14,6 +14,7 @@ from django.conf import settings from django.core.exceptions import ObjectDoesNotExist, PermissionDenied from django.core.serializers.json import DjangoJSONEncoder from django.utils.translation import force_text +from django.utils import six from requests.exceptions import RequestException @@ -33,6 +34,28 @@ class APIError(RuntimeError): super(APIError, self).__init__(*args) +def exception_to_text(e): + try: + return six.text_type(e) + except Exception: + pass + + try: + return six.text_type(repr(e)) + except Exception: + pass + + try: + args = e.args + try: + content = six.text_type(repr(args)) if args != [] else '' + except Exception: + content = '' + except AttributeError: + content = '' + return u'%s(%s)' % (e.__class__.__name__, content) + + class JSONEncoder(DjangoJSONEncoder): def default(self, o): if isinstance(o, time.struct_time): @@ -125,7 +148,7 @@ class to_json(object): data = self.obj_to_response(req, resp) status = 200 except Exception as e: - extras = {'method': req.method, 'exception': repr(e)} + extras = {'method': req.method, 'exception': exception_to_text(e)} if not self.logger: extras['request'] = req if req.method == 'POST': diff --git a/tests/test_base_adresse.py b/tests/test_base_adresse.py index 8ac5200..9d3e400 100644 --- a/tests/test_base_adresse.py +++ b/tests/test_base_adresse.py @@ -86,6 +86,7 @@ def test_base_adresse_search_qs_parameters_error(app, base_adresse, resp = app.get('/base-adresse/%s/search' % base_adresse.slug, status=400) assert resp.json['err'] == 1 assert resp.json['err_class'] == 'passerelle.views.WrongParameter' + assert resp.json['err_desc'] == u"missing parameters: 'q'." # json-api serializer resp = app.get('/base-adresse/%s/streets?zipcode=13400&coin=zz' % base_adresse.slug, status=400) assert resp.json['err'] == 1 -- 2.20.1