lfs: improve the hints for common errors in the Batch API
authorMatt Harbison <matt_harbison@yahoo.com>
Thu, 15 Nov 2018 17:58:59 -0500
changeset 40701 9f78d10742af
parent 40700 8863f08c1630
child 40702 380f5131ee7b
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.
hgext/lfs/blobstore.py
tests/test-lfs-serve-access.t
--- a/hgext/lfs/blobstore.py	Thu Nov 15 17:55:01 2018 -0500
+++ b/hgext/lfs/blobstore.py	Thu Nov 15 17:58:59 2018 -0500
@@ -271,9 +271,14 @@
             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:
--- a/tests/test-lfs-serve-access.t	Thu Nov 15 17:55:01 2018 -0500
+++ b/tests/test-lfs-serve-access.t	Thu Nov 15 17:58:59 2018 -0500
@@ -30,7 +30,7 @@
   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 @@
   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 @@
   $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 @@
   $ "$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)