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:
parent
5cca99bbae
commit
c7f6c55423
2 changed files with 29 additions and 2 deletions
scripts/python/TerraSync/terrasync
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue