1
0
Fork 0

terrasync.py: user-friendly error message when no 'path' found in .dirindex

During the recent SourceForge migration, the TerraSync server hosted
there used to send .dirindex files with the following contents:

  Project web is currently offline pending the final migration of its
  data to our new datacenter.

Make sure terrasync.py aborts with a user-understandable error in such a
case.
This commit is contained in:
Florent Rougon 2018-02-16 11:57:31 +01:00
parent 5cca99bbae
commit c7f6c55423
2 changed files with 29 additions and 2 deletions

View file

@ -64,3 +64,12 @@ class UserError(TerraSyncPyException):
class NetworkError(TerraSyncPyException):
"""Exception raised when getting a network error even after retrying."""
ExceptionShortDescription = "Network error"
class RepoDataError(TerraSyncPyException):
"""
Exception raised when getting invalid data from the TerraSync repository."""
ExceptionShortDescription = "Invalid data from the TerraSync repository"
class InvalidDirIndexFile(RepoDataError):
"""Exception raised when getting invalid data from a .dirindex file."""
ExceptionShortDescription = "Invalid .dirindex file"

View file

@ -34,7 +34,8 @@ from http.client import HTTPConnection, _CS_IDLE, HTTPException
from os import listdir
from os.path import isfile, isdir, join
from .exceptions import UserError, NetworkError
from .exceptions import UserError, NetworkError, RepoDataError, \
InvalidDirIndexFile
from .virtual_path import VirtualPath
@ -186,11 +187,19 @@ class DirIndex:
self.version = 0
self.path = None # will be a VirtualPath instance when set
# readFrom() stores the raw contents of the .dirindex file in this
# attribute. This is useful for troubleshooting.
self._rawContents = None
with open(dirIndexFile) as f:
self.readFrom(f)
self._sanityCheck()
def readFrom(self, readable):
for line in readable:
self._rawContents = readable.read()
for line in self._rawContents.split('\n'):
line = line.strip()
if line.startswith('#'):
continue
@ -212,6 +221,15 @@ class DirIndex:
elif tokens[0] == "f":
self.f.append({ 'name': tokens[1], 'hash': tokens[2], 'size': tokens[3] })
def _sanityCheck(self):
if self.path is None:
assert self._rawContents is not None
firstLines = self._rawContents.split('\n')[:5]
raise InvalidDirIndexFile(
"no 'path' field found; the first lines of this .dirindex file "
"follow:\n\n" + '\n'.join(firstLines))
def getVersion(self):
return self.version