[CORD-2702] Replacing Django's DoesNotExist with XOSNotFound for better API response

Change-Id: I44e55bf13b6e19370d20df43e26114e033ff40b7
(cherry picked from commit b1286b31f691edcd96a880dff9fb082e7b1704b3)
diff --git a/xos/coreapi/apihelper.py b/xos/coreapi/apihelper.py
index 271e094..7c8c6a0 100644
--- a/xos/coreapi/apihelper.py
+++ b/xos/coreapi/apihelper.py
@@ -23,6 +23,7 @@
 from protos import xos_pb2
 from google.protobuf.empty_pb2 import Empty
 import grpc
+import json
 
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.auth import authenticate as django_authenticate
@@ -89,6 +90,8 @@
                 context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
             elif (isinstance(e, XOSNotAuthenticated)):
                 context.set_code(grpc.StatusCode.UNAUTHENTICATED)
+            elif (isinstance(e, XOSNotFound)):
+                context.set_code(grpc.StatusCode.NOT_FOUND)
             raise
     return wrapper
 
@@ -396,17 +399,20 @@
 
     def get_live_or_deleted_object(self, djangoClass, id):
         """ Given an id, retrieve the object regardless of whether the object is live or deleted. """
-        obj = None
-        # First, check to see if the object has been deleted. Maybe the caller is
-        # trying to update the policed timestamp of a deleted object.
-        if hasattr(djangoClass, "deleted_objects"):
-            deleted_objects = djangoClass.deleted_objects.filter(id=id)
-            if deleted_objects:
-                obj = deleted_objects[0]
-        # No deleted object was found, so check for a live object.
-        if not obj:
-            obj = djangoClass.objects.get(id=id)
-        return obj
+        try:
+            obj = None
+            # First, check to see if the object has been deleted. Maybe the caller is
+            # trying to update the policed timestamp of a deleted object.
+            if hasattr(djangoClass, "deleted_objects"):
+                deleted_objects = djangoClass.deleted_objects.filter(id=id)
+                if deleted_objects:
+                    obj = deleted_objects[0]
+            # No deleted object was found, so check for a live object.
+            if not obj:
+                obj = djangoClass.objects.get(id=id)
+            return obj
+        except djangoClass.DoesNotExist, e:
+            raise XOSNotFound(fields={'id': id, 'message': e.message})
 
     def xos_security_gate(self, obj, user, **access_types):
         sec_ctx = XOSDefaultSecurityContext()