More error reporting from TerraSync/HTTP

- raise more errors when requests fail, and report/catch these.
This commit is contained in:
James Turner
2016-02-25 21:20:33 +02:00
parent 6cef1f9091
commit 0b4f416ddc
2 changed files with 73 additions and 20 deletions

View File

@@ -133,7 +133,9 @@ public:
std::string computeHashForPath(const SGPath& p);
void writeHashCache();
void failedToGetRootIndex();
void failedToGetRootIndex(AbstractRepository::ResultCode st);
void failedToUpdateChild(const SGPath& relativePath,
AbstractRepository::ResultCode fileStatus);
typedef std::vector<HTTP::Request_ptr> RequestVector;
RequestVector requests;
@@ -200,7 +202,7 @@ public:
if (p.exists()) {
try {
// already exists on disk
parseDirIndex(children);
bool ok = parseDirIndex(children);
std::sort(children.begin(), children.end());
} catch (sg_exception& e) {
// parsing cache failed
@@ -234,13 +236,14 @@ public:
std::sort(children.begin(), children.end());
}
void failedToUpdate()
void failedToUpdate(AbstractRepository::ResultCode status)
{
if (_relativePath.isNull()) {
// root dir failed
_repository->failedToGetRootIndex();
_repository->failedToGetRootIndex(status);
} else {
SG_LOG(SG_TERRASYNC, SG_WARN, "failed to update dir:" << _relativePath);
_repository->failedToUpdateChild(_relativePath, status);
}
}
@@ -277,8 +280,6 @@ public:
p.append(c->name);
HTTPDirectory* childDir = _repository->getOrCreateDirectory(p.str());
childDir->updateChildrenBasedOnHash();
} else {
SG_LOG(SG_TERRASYNC, SG_INFO, "existing file is ok:" << c->name);
}
}
@@ -357,11 +358,13 @@ public:
SG_LOG(SG_TERRASYNC, SG_INFO, "did update:" << fpath);
}
void didFailToUpdateFile(const std::string& file)
void didFailToUpdateFile(const std::string& file,
AbstractRepository::ResultCode status)
{
SGPath fpath(_relativePath);
fpath.append(file);
SG_LOG(SG_TERRASYNC, SG_WARN, "failed to update:" << fpath);
_repository->failedToUpdateChild(fpath, status);
}
private:
@@ -379,10 +382,14 @@ private:
return std::find_if(children.begin(), children.end(), ChildWithName(name));
}
void parseDirIndex(ChildInfoList& children)
bool parseDirIndex(ChildInfoList& children)
{
SGPath p(absolutePath());
p.append(".dirindex");
if (!p.exists()) {
return false;
}
std::ifstream indexStream( p.c_str(), std::ios::in );
if ( !indexStream.is_open() ) {
@@ -427,6 +434,8 @@ private:
children.back().setSize(sizeData);
}
}
return true;
}
void removeChild(const std::string& name)
@@ -448,6 +457,7 @@ private:
if (!ok) {
SG_LOG(SG_TERRASYNC, SG_WARN, "removal failed for:" << p);
throw sg_io_exception("Failed to remove existing file/dir:", p);
}
}
@@ -561,12 +571,21 @@ HTTPRepository::failure() const
directory->didUpdateFile(fileName, hash);
SG_LOG(SG_TERRASYNC, SG_DEBUG, "got file " << fileName << " in " << directory->absolutePath());
} else if (responseCode() == 404) {
directory->didFailToUpdateFile(fileName, AbstractRepository::REPO_ERROR_FILE_NOT_FOUND);
} else {
directory->didFailToUpdateFile(fileName);
directory->didFailToUpdateFile(fileName, AbstractRepository::REPO_ERROR_HTTP);
}
directory->repository()->finishedRequest(this);
}
virtual void onFail()
{
file.reset();
directory->didFailToUpdateFile(fileName, AbstractRepository::REPO_ERROR_SOCKET);
directory->repository()->finishedRequest(this);
}
private:
static std::string makeUrl(HTTPDirectory* d, const std::string& file)
{
@@ -645,15 +664,27 @@ HTTPRepository::failure() const
}
// either way we've confirmed the index is valid so update
// children now
directory->updateChildrenBasedOnHash();
try {
// either way we've confirmed the index is valid so update
// children now
directory->updateChildrenBasedOnHash();
} catch (sg_exception& e) {
directory->failedToUpdate(AbstractRepository::REPO_ERROR_IO);
}
} else if (responseCode() == 404) {
directory->failedToUpdate(AbstractRepository::REPO_ERROR_FILE_NOT_FOUND);
} else {
directory->failedToUpdate();
directory->failedToUpdate(AbstractRepository::REPO_ERROR_HTTP);
}
directory->repository()->finishedRequest(this);
}
virtual void onFail()
{
directory->failedToUpdate(AbstractRepository::REPO_ERROR_SOCKET);
directory->repository()->finishedRequest(this);
}
private:
static std::string makeUrl(HTTPDirectory* d)
{
@@ -677,16 +708,16 @@ HTTPRepository::failure() const
HTTP::Request_ptr HTTPRepoPrivate::updateFile(HTTPDirectory* dir, const std::string& name)
{
HTTP::Request_ptr r(new FileGetRequest(dir, name));
http->makeRequest(r);
requests.push_back(r);
http->makeRequest(r);
return r;
}
HTTP::Request_ptr HTTPRepoPrivate::updateDir(HTTPDirectory* dir)
{
HTTP::Request_ptr r(new DirGetRequest(dir));
http->makeRequest(r);
requests.push_back(r);
http->makeRequest(r);
return r;
}
@@ -863,7 +894,7 @@ HTTPRepository::failure() const
{
RequestVector::iterator it = std::find(requests.begin(), requests.end(), req);
if (it == requests.end()) {
throw sg_exception("lost request somehow");
throw sg_exception("lost request somehow", req->url());
}
requests.erase(it);
if (requests.empty()) {
@@ -871,11 +902,19 @@ HTTPRepository::failure() const
}
}
void HTTPRepoPrivate::failedToGetRootIndex()
void HTTPRepoPrivate::failedToGetRootIndex(AbstractRepository::ResultCode st)
{
SG_LOG(SG_TERRASYNC, SG_WARN, "Failed to get root of repo:" << baseUrl);
status = AbstractRepository::REPO_ERROR_NOT_FOUND;
status = st;
}
void HTTPRepoPrivate::failedToUpdateChild(const SGPath& relativePath,
AbstractRepository::ResultCode fileStatus)
{
// this means we only record the last error, should this be improved?
status = fileStatus;
}
} // of namespace simgear

View File

@@ -664,7 +664,16 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
}
slot.repository->setBaseUrl(serverUrl + "/" + slot.currentItem._dir);
slot.repository->update();
try {
slot.repository->update();
} catch (sg_exception& e) {
SG_LOG(SG_TERRASYNC, SG_INFO, "sync of " << slot.repository->baseUrl() << " failed to start with error:"
<< e.getFormattedMessage());
fail(slot.currentItem);
slot.busy = false;
slot.repository.reset();
return;
}
slot.nextWarnTimeout = 20000;
slot.stamp.stamp();
@@ -676,7 +685,12 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
void SGTerraSync::SvnThread::runInternal()
{
while (!_stop) {
_http.update(100);
try {
_http.update(100);
} catch (sg_exception& e) {
SG_LOG(SG_TERRASYNC, SG_WARN, "failure doing HTTP update" << e.getFormattedMessage());
}
_transfer_rate = _http.transferRateBytesPerSec();
// convert from bytes to kbytes
_total_kb_downloaded = static_cast<int>(_http.totalBytesDownloaded() / 1024);