hgext/lfs/blobstore.py
changeset 35666 2c6ebd0c850e
parent 35614 6d6d20658cce
child 35694 8a23082f4d93
--- a/hgext/lfs/blobstore.py	Sun Jan 14 18:12:51 2018 -0500
+++ b/hgext/lfs/blobstore.py	Wed Jan 10 21:27:05 2018 -0800
@@ -227,20 +227,27 @@
                                  % rawjson)
         return response
 
-    def _checkforservererror(self, pointers, responses):
+    def _checkforservererror(self, pointers, responses, action):
         """Scans errors from objects
 
         Returns LfsRemoteError if any objects has an error"""
         for response in responses:
-            error = response.get('error')
-            if error:
+            # The server should return 404 when objects cannot be found. Some
+            # server implementation (ex. lfs-test-server)  does not set "error"
+            # but just removes "download" from "actions". Treat that case
+            # as the same as 404 error.
+            notfound = (response.get('error', {}).get('code') == 404
+                        or (action == 'download'
+                            and action not in response.get('actions', [])))
+            if notfound:
                 ptrmap = {p.oid(): p for p in pointers}
                 p = ptrmap.get(response['oid'], None)
-                if error['code'] == 404 and p:
+                if p:
                     filename = getattr(p, 'filename', 'unknown')
                     raise LfsRemoteError(
                         _(('LFS server error. Remote object '
                           'for "%s" not found: %r')) % (filename, response))
+            if 'error' in response:
                 raise LfsRemoteError(_('LFS server error: %r') % response)
 
     def _extractobjects(self, response, pointers, action):
@@ -252,21 +259,11 @@
         """
         # Scan errors from objects - fail early
         objects = response.get('objects', [])
-        self._checkforservererror(pointers, objects)
+        self._checkforservererror(pointers, objects, action)
 
         # Filter objects with given action. Practically, this skips uploading
         # objects which exist in the server.
         filteredobjects = [o for o in objects if action in o.get('actions', [])]
-        # But for downloading, we want all objects. Therefore missing objects
-        # should be considered an error.
-        if action == 'download':
-            if len(filteredobjects) < len(objects):
-                missing = [o.get('oid', '?')
-                           for o in objects
-                           if action not in o.get('actions', [])]
-                raise LfsRemoteError(
-                    _('LFS server claims required objects do not exist:\n%s')
-                    % '\n'.join(missing))
 
         return filteredobjects