commit 9fa1d0c968977ef23e26556b0a8e8e76b32c7288
Author: Christian Heimes <cheimes@redhat.com>
Date: Wed Jul 15 17:55:05 2015 +0200
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
diff --git a/base/common/python/pki/__init__.py b/base/common/python/pki/__init__.py
index c383cdb..39a0db7 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