Patchwork [3,of,5] lfs: improve the hints for common errors in the Batch API

login
register
mail settings
Submitter Matt Harbison
Date Nov. 16, 2018, 2:53 a.m.
Message ID <8004aa5e1952fad796b9.1542336832@Envy>
Download mbox | patch
Permalink /patch/36620/
State Accepted
Headers show

Comments

Matt Harbison - Nov. 16, 2018, 2:53 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1542322739 18000
#      Thu Nov 15 17:58:59 2018 -0500
# Node ID 8004aa5e1952fad796b927f829b618927512e4a7
# Parent  872ad0231ff2b33efe2a66a919221b89320b0f7e
lfs: improve the hints for common errors in the Batch API

The previous message was too debug-ish and less action oriented than a hint
should be.  The remaining errors that aren't handled are more along the lines of
programming errors (not using POST, bad accept type, etc), so I'm not bothering
with that.

The friendly errors purposely use `self.baseurl` instead of the full Batch API
endpoint because I'd expect some copy/paste/modify on the part of the user here,
and it would be more confusing if '/objects/batch' magically appeared, but
shouldn't be used in the config setting.  It still seems like the right thing
for debugging in the catchall case.

Patch

diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py
--- a/hgext/lfs/blobstore.py
+++ b/hgext/lfs/blobstore.py
@@ -271,9 +271,14 @@  class _gitlfsremote(object):
             rsp = self.urlopener.open(batchreq)
             rawjson = rsp.read()
         except util.urlerr.httperror as ex:
-            raise LfsRemoteError(_('LFS HTTP error: %s') % ex,
-                                 hint=_('api=%s, action=%s')
-                                 % (url, action))
+            hints = {
+                400: _('check that lfs serving is enabled on %s and "%s" is '
+                       'supported') % (self.baseurl, action),
+                404: _('the "lfs.url" config may be used to override %s')
+                       % self.baseurl,
+            }
+            hint = hints.get(ex.code, _('api=%s, action=%s') % (url, action))
+            raise LfsRemoteError(_('LFS HTTP error: %s') % ex, hint=hint)
         try:
             response = json.loads(rawjson)
         except ValueError:
diff --git a/tests/test-lfs-serve-access.t b/tests/test-lfs-serve-access.t
--- a/tests/test-lfs-serve-access.t
+++ b/tests/test-lfs-serve-access.t
@@ -30,7 +30,7 @@  Uploads fail...
   pushing to http://localhost:$HGPORT/
   searching for changes
   abort: LFS HTTP error: HTTP Error 400: no such method: .git!
-  (api=http://localhost:$HGPORT/.git/info/lfs/objects/batch, action=upload)
+  (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "upload" is supported)
   [255]
 
 ... so do a local push to make the data available.  Remove the blob from the
@@ -52,7 +52,7 @@  Downloads fail...
   new changesets 525251863cad
   updating to branch default
   abort: LFS HTTP error: HTTP Error 400: no such method: .git!
-  (api=http://localhost:$HGPORT/.git/info/lfs/objects/batch, action=download)
+  (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "download" is supported)
   [255]
 
   $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
@@ -68,14 +68,21 @@  Downloads fail...
   $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
   $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
 
-Blob URIs are correct when --prefix is used
-
   $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
   $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server serve -d \
   >    -p $HGPORT --pid-file=hg.pid --prefix=subdir/mount/point \
   >    -A $TESTTMP/access.log -E $TESTTMP/errors.log
   $ cat hg.pid >> $DAEMON_PIDS
 
+Reasonable hint for a misconfigured blob server
+
+  $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT/missing
+  abort: LFS HTTP error: HTTP Error 404: Not Found!
+  (the "lfs.url" config may be used to override http://localhost:$HGPORT/missing)
+  [255]
+
+Blob URIs are correct when --prefix is used
+
   $ hg clone --debug http://localhost:$HGPORT/subdir/mount/point cloned2
   using http://localhost:$HGPORT/subdir/mount/point
   sending capabilities command
@@ -148,6 +155,7 @@  Blob URIs are correct when --prefix is u
   $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
 
   $ cat $TESTTMP/access.log $TESTTMP/errors.log
+  $LOCALIP - - [$LOGDATE$] "POST /missing/objects/batch HTTP/1.1" 404 - (glob)
   $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=capabilities HTTP/1.1" 200 - (glob)
   $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
   $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)