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
scripts/python/TerraSync/terrasync

View file

@ -64,3 +64,12 @@ class UserError(TerraSyncPyException):
class NetworkError(TerraSyncPyException): class NetworkError(TerraSyncPyException):
"""Exception raised when getting a network error even after retrying.""" """Exception raised when getting a network error even after retrying."""
ExceptionShortDescription = "Network error" 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 import listdir
from os.path import isfile, isdir, join from os.path import isfile, isdir, join
from .exceptions import UserError, NetworkError from .exceptions import UserError, NetworkError, RepoDataError, \
InvalidDirIndexFile
from .virtual_path import VirtualPath from .virtual_path import VirtualPath
@ -186,11 +187,19 @@ class DirIndex:
self.version = 0 self.version = 0
self.path = None # will be a VirtualPath instance when set 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: with open(dirIndexFile) as f:
self.readFrom(f) self.readFrom(f)
self._sanityCheck()
def readFrom(self, readable): def readFrom(self, readable):
for line in readable: self._rawContents = readable.read()
for line in self._rawContents.split('\n'):
line = line.strip() line = line.strip()
if line.startswith('#'): if line.startswith('#'):
continue continue
@ -212,6 +221,15 @@ class DirIndex:
elif tokens[0] == "f": elif tokens[0] == "f":
self.f.append({ 'name': tokens[1], 'hash': tokens[2], 'size': tokens[3] }) 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): def getVersion(self):
return self.version return self.version