Mercurial > hg
comparison hgext/lfs/blobstore.py @ 37242:67db84842356
lfs: improve the client message when the server signals an object error
Two things here. First, the previous message included a snippet of JSON, which
tends to be long (and in the case of lfs-test-server, has no error message).
Instead, give a concise message where possible, and leave the JSON to a debug
output. Second, the server can signal issues other than a missing individual
file. This change shows a corrupt file, but I'm debating letting the corrupt
file get downloaded, because 1) the error code doesn't really fit, and 2) having
it locally makes forensics easier. Maybe need a config knob for that.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Sun, 25 Feb 2018 23:44:02 -0500 |
parents | b00bd974eef5 |
children | 3e293808e835 |
comparison
equal
deleted
inserted
replaced
37241:79af9ae46a78 | 37242:67db84842356 |
---|---|
261 for response in responses: | 261 for response in responses: |
262 # The server should return 404 when objects cannot be found. Some | 262 # The server should return 404 when objects cannot be found. Some |
263 # server implementation (ex. lfs-test-server) does not set "error" | 263 # server implementation (ex. lfs-test-server) does not set "error" |
264 # but just removes "download" from "actions". Treat that case | 264 # but just removes "download" from "actions". Treat that case |
265 # as the same as 404 error. | 265 # as the same as 404 error. |
266 notfound = (response.get('error', {}).get('code') == 404 | 266 if 'error' not in response: |
267 or (action == 'download' | 267 if (action == 'download' |
268 and action not in response.get('actions', []))) | 268 and action not in response.get('actions', [])): |
269 if notfound: | 269 code = 404 |
270 ptrmap = {p.oid(): p for p in pointers} | |
271 p = ptrmap.get(response['oid'], None) | |
272 if p: | |
273 filename = getattr(p, 'filename', 'unknown') | |
274 raise LfsRemoteError( | |
275 _(('LFS server error. Remote object ' | |
276 'for "%s" not found: %r')) % (filename, response)) | |
277 else: | 270 else: |
278 raise LfsRemoteError( | 271 continue |
279 _('LFS server error. Unsolicited response for oid %s') | 272 else: |
280 % response['oid']) | 273 # An error dict without a code doesn't make much sense, so |
281 if 'error' in response: | 274 # treat as a server error. |
282 raise LfsRemoteError(_('LFS server error: %r') % response) | 275 code = response.get('error').get('code', 500) |
276 | |
277 ptrmap = {p.oid(): p for p in pointers} | |
278 p = ptrmap.get(response['oid'], None) | |
279 if p: | |
280 filename = getattr(p, 'filename', 'unknown') | |
281 errors = { | |
282 404: 'The object does not exist', | |
283 410: 'The object was removed by the owner', | |
284 422: 'Validation error', | |
285 500: 'Internal server error', | |
286 } | |
287 msg = errors.get(code, 'status code %d' % code) | |
288 raise LfsRemoteError(_('LFS server error for "%s": %s') | |
289 % (filename, msg)) | |
290 else: | |
291 raise LfsRemoteError( | |
292 _('LFS server error. Unsolicited response for oid %s') | |
293 % response['oid']) | |
283 | 294 |
284 def _extractobjects(self, response, pointers, action): | 295 def _extractobjects(self, response, pointers, action): |
285 """extract objects from response of the batch API | 296 """extract objects from response of the batch API |
286 | 297 |
287 response: parsed JSON object returned by batch API | 298 response: parsed JSON object returned by batch API |