Blame SOURCES/pki-core-handle-JSON-decode-error.patch

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