diff options
author | Christian Heimes <cheimes@redhat.com> | 2015-07-15 17:55:05 +0200 |
---|---|---|
committer | Christian Heimes <cheimes@redhat.com> | 2015-07-15 21:19:54 +0200 |
commit | 9fa1d0c968977ef23e26556b0a8e8e76b32c7288 (patch) | |
tree | 9acac7d02a5020e204de639c69d25e70a4b654f7 /base | |
parent | 4aa89241e3a0423198cc6dce1f6f193eca74cac6 (diff) | |
download | pki-9fa1d0c968977ef23e26556b0a8e8e76b32c7288.tar.gz pki-9fa1d0c968977ef23e26556b0a8e8e76b32c7288.tar.xz pki-9fa1d0c968977ef23e26556b0a8e8e76b32c7288.zip |
Handle JSON decode error in handle_exceptions()
pki.handle_exceptions() raises a JSON decode exception when the body of
the HTTPException is not a valid JSON string. The JSON exception hides
the true error message.
The patch also fixes a bug in PKIException.from_json(). The code and
ClassName attribute are now correctly set. Finally we have our first
unit test.
https://fedorahosted.org/pki/ticket/1488
https://fedorahosted.org/freeipa/ticket/5129
Diffstat (limited to 'base')
-rw-r--r-- | base/common/python/pki/__init__.py | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/base/common/python/pki/__init__.py b/base/common/python/pki/__init__.py index c383cdb4d..39a0db717 100644 --- a/base/common/python/pki/__init__.py +++ b/base/common/python/pki/__init__.py @@ -24,6 +24,7 @@ This module contains top-level classes and functions used by the Dogtag project. from functools import wraps import os import re +import sys import requests @@ -205,10 +206,12 @@ class PKIException(Exception, ResourceMessage): :type json_value: str :return: pki.PKIException """ - ret = cls(json_value['Message'], json_value['Code'], - json_value['ClassName']) + ret = cls( + message=json_value['Message'], + code=json_value['Code'], + class_name=json_value['ClassName'] + ) for attr in json_value['Attributes']['Attribute']: - print str(attr) ret.add_attribute(attr["name"], attr["value"]) return ret @@ -293,15 +296,25 @@ def handle_exceptions(): """ Decorator to catch and re-throw PKIExceptions.""" try: return fn_call(inst, *args, **kwargs) - except requests.exceptions.HTTPError as exc: - clazz = exc.response.json()['ClassName'] - if clazz in EXCEPTION_MAPPINGS: - exception_class = EXCEPTION_MAPPINGS[clazz] - pki_exception = exception_class.from_json( - exc.response.json()) - raise pki_exception + except requests.exceptions.HTTPError: + # store exception information. json may raise another + # exception. We want to re-raise the HTTPError. + exc_type, exc_val, exc_tb = sys.exc_info() + try: + json = exc_val.response.json() + except ValueError: + # json raises ValueError. simplejson raises + # JSONDecodeError, which is a subclass of ValueError. + # re-raise original exception + raise exc_type, exc_val, exc_tb else: - raise exc + # clear reference cycle + exc_type = exc_val = exc_tb = None + clazz = json.get('ClassName') + if clazz and clazz in EXCEPTION_MAPPINGS: + exception_class = EXCEPTION_MAPPINGS[clazz] + pki_exception = exception_class.from_json(json) + raise pki_exception return handler |