Repository: box/box-python-sdk
Pull request #49 (2015-05-21 04:06:55)

It would be helpful to include context_info in the BoxAPIException
For example when trying you create a folder that already exists you will get back a list of conflicts in the context_info in the response.


Patch:
diff --git a/boxsdk/exception.py b/boxsdk/exception.py
index ae012d7..7ad9de1 100644
--- a/boxsdk/exception.py
+++ b/boxsdk/exception.py
@@ -23,7 +23,7 @@ class BoxAPIException(BoxException):
     """
     Exception raised from the box session layer.
     """
-    def __init__(self, status, code=None, message=None, request_id=None, headers=None, url=None, method=None):
+    def __init__(self, status, code=None, message=None, request_id=None, headers=None, url=None, method=None, context_info=None):
         """
         :param status:
             HTTP status code of the failed response
@@ -53,6 +53,10 @@ def __init__(self, status, code=None, message=None, request_id=None, headers=Non
             The HTTP verb used to make the request.
         :type method:
             `unicode`
+        :param context_info:
+            The context_info returned in the failed response.
+        :type context_info:
+            `dict`
         """
         super(BoxAPIException, self).__init__()
         self._status = status
@@ -62,9 +66,10 @@ def __init__(self, status, code=None, message=None, request_id=None, headers=Non
         self._headers = headers
         self._url = url
         self._method = method
+        self._context_info = context_info
 
     def __unicode__(self):
-        return '\nMessage: {0}\nStatus: {1}\nCode: {2}\nRequest id: {3}\nHeaders: {4}\nURL: {5}\nMethod: {6}'.format(
+        return '\nMessage: {0}\nStatus: {1}\nCode: {2}\nRequest id: {3}\nHeaders: {4}\nURL: {5}\nMethod: {6}\nContext info: {7}'.format(
             self._message,
             self._status,
             self._code,
@@ -72,6 +77,7 @@ def __unicode__(self):
             self._headers,
             self._url,
             self._method,
+            self._context_info,
         )
 
     @property
@@ -118,6 +124,14 @@ def method(self):
         """
         return self._method
 
+    @property
+    def context_info(self):
+        """
+        The context_info returned in the failed response.
+        :rtype: `dict`
+        """
+        return self._context_info
+
 
 class BoxOAuthException(BoxException):
     """
diff --git a/boxsdk/session/box_session.py b/boxsdk/session/box_session.py
index a015739..cfe50b7 100644
--- a/boxsdk/session/box_session.py
+++ b/boxsdk/session/box_session.py
@@ -175,6 +175,7 @@ def _raise_on_unsuccessful_request(self, network_response, expect_json_response,
                 request_id=response_json.get('request_id', None),
                 url=url,
                 method=method,
+                context_info=response_json.get('context_info', None),
             )
         if expect_json_response and not self._is_json_response(network_response):
             raise BoxAPIException(


Test patch:
diff --git a/test/unit/test_exception.py b/test/unit/test_exception.py
index 469259f..6539f84 100644
--- a/test/unit/test_exception.py
+++ b/test/unit/test_exception.py
@@ -12,6 +12,7 @@ def test_box_api_exception():
     headers = {'header': 'value'}
     url = 'https://example.com'
     method = 'GET'
+    context_info = {'context': 'value'}
     box_exception = BoxAPIException(
         status,
         code=code,
@@ -20,6 +21,7 @@ def test_box_api_exception():
         headers=headers,
         url=url,
         method=method,
+        context_info=context_info,
     )
     assert box_exception.status == status
     assert box_exception.code == code
@@ -35,7 +37,8 @@ def test_box_api_exception():
 Request id: {3}
 Headers: {4}
 URL: {5}
-Method: {6}'''.format(message, status, code, request_id, headers, url, method)
+Method: {6}
+Context info: {7}'''.format(message, status, code, request_id, headers, url, method, context_info)
 
 
 def test_box_oauth_exception():