From 721a8f79ab3c997ee9f31daa3b2307894730d8d4 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Sun, 5 May 2013 11:41:31 +0200 Subject: [PATCH] Improve error handling, add error string to each individual file item. --- src/mirall/csyncthread.cpp | 28 ++++++++++++----- src/mirall/csyncthread.h | 2 +- src/mirall/owncloudpropagator.cpp | 50 ++++++++++++++----------------- src/mirall/owncloudpropagator.h | 4 ++- src/mirall/syncfileitem.h | 5 ++++ 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/mirall/csyncthread.cpp b/src/mirall/csyncthread.cpp index 4de794706..eebaed8e8 100644 --- a/src/mirall/csyncthread.cpp +++ b/src/mirall/csyncthread.cpp @@ -61,7 +61,7 @@ CSyncThread::~CSyncThread() } -QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errString ) +QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err ) const { QString errStr; @@ -110,7 +110,7 @@ QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errSt case CSYNC_ERR_ACCESS_FAILED: errStr = tr("

The target directory does not exist.

Please check the sync setup.

"); // this is critical. The database has to be removed. - emit wipeDb(); + // emit wipeDb(); FIXME - what about this? break; case CSYNC_ERR_REMOTE_CREATE: case CSYNC_ERR_REMOTE_STAT: @@ -160,9 +160,6 @@ QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errSt errStr = tr("An internal error number %1 happend.").arg( (int) err ); } - if( errString ) { - errStr += tr("
Backend Message: ")+QString::fromUtf8(errString); - } return errStr; } @@ -299,7 +296,11 @@ struct CSyncRunScopeHelper { void CSyncThread::handleSyncError(CSYNC *ctx, const char *state) { CSYNC_ERROR_CODE err = csync_get_error( ctx ); const char *errMsg = csync_get_error_string( ctx ); - QString errStr = csyncErrorToString(err, errMsg); + QString errStr = csyncErrorToString(err); + if( errMsg ) { + errStr += QLatin1String("
"); + errStr += QString::fromUtf8(errMsg); + } qDebug() << " #### ERROR during "<< state << ": " << errStr; switch (err) { case CSYNC_ERR_SERVICE_UNAVAILABLE: @@ -384,6 +385,19 @@ void CSyncThread::startSync() propagator._etag.clear(); // FIXME : set to the right one a.instruction = propagator.propagate(item); + // if the propagator had an error for a file, put the error string into the synced item + if( propagator._errorCode != CSYNC_ERR_NONE ) { + // find the real object to add the err message. The loop only handles const refs. + SyncFileItemVector::iterator it = qBinaryFind(_syncedItems.begin(), _syncedItems.end(), item); + if ( it != _syncedItems.end()) { + QMutexLocker locker(&_mutex); + it->_errorString = csyncErrorToString( propagator._errorCode ); + it->_errorDetail = propagator._errorString; + it->_httpCode = propagator._httpStatusCode; + qDebug() << "File " << item._file << " propagator error " << item._errorString; + } + } + if (item._isDirectory && item._instruction == CSYNC_INSTRUCTION_REMOVE && a.instruction == CSYNC_INSTRUCTION_DELETED) { lastDeleted = item._file; @@ -400,7 +414,7 @@ void CSyncThread::startSync() performedActions.insert(item._renameTarget, a); } - //TODO record errors and progress; + //TODO progress; } // if( csync_propagate(_csync_ctx) < 0 ) { diff --git a/src/mirall/csyncthread.h b/src/mirall/csyncthread.h index 167375eba..4698b45ae 100644 --- a/src/mirall/csyncthread.h +++ b/src/mirall/csyncthread.h @@ -46,7 +46,7 @@ public: CSyncThread(CSYNC *, const QString &localPath, const QString &remotePath); ~CSyncThread(); - QString csyncErrorToString( CSYNC_ERROR_CODE, const char * ); + QString csyncErrorToString(CSYNC_ERROR_CODE) const; Q_INVOKABLE void startSync(); diff --git a/src/mirall/owncloudpropagator.cpp b/src/mirall/owncloudpropagator.cpp index 8f5dbd558..2f0ba8228 100644 --- a/src/mirall/owncloudpropagator.cpp +++ b/src/mirall/owncloudpropagator.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -294,18 +293,10 @@ void OwncloudPropagator::updateMTimeAndETag(const char* uri, time_t mtime) QScopedPointer req(ne_request_create(_session, "HEAD", uri)); int neon_stat = ne_request_dispatch(req.data()); - if( neon_stat != NE_OK ) { - updateErrorFromSession(neon_stat); + if( updateErrorFromSession(neon_stat, req.data()) ) { + // error happend + qDebug() << "Could not issue HEAD request for ETag."; } else { - const ne_status *stat = ne_get_status( req.data() ); - - if( stat && stat->klass != 2 ) { - _httpStatusCode = stat->code; - _errorCode = CSYNC_ERR_HTTP; - _errorString = QString::fromUtf8( stat->reason_phrase ); - } - } - if( _errorCode == CSYNC_ERR_NONE ) { _etag = parseEtag(req.data()); } } @@ -415,19 +406,9 @@ csync_instructions_e OwncloudPropagator::downloadFile(const SyncFileItem &item, ne_unhook_post_headers( _session, DownloadContext::install_content_reader, &writeCtx ); // ne_set_notifier(_session, 0, 0); - if( neon_stat != NE_OK ) { - updateErrorFromSession(neon_stat); + if( updateErrorFromSession(neon_stat, req.data() ) ) { qDebug("Error GET: Neon: %d", neon_stat); return CSYNC_INSTRUCTION_ERROR; - } else { - const ne_status *status = ne_get_status( req.data() ); - qDebug("GET http result %d (%s)", status->code, status->reason_phrase ? status->reason_phrase : "klass != 2 ) { - qDebug("sendfile request failed with http status %d!", status->code); - _httpStatusCode = status->code; - _errorString = QString::fromUtf8(status->reason_phrase); - return CSYNC_INSTRUCTION_ERROR; - } } _etag = parseEtag(req.data()); @@ -531,18 +512,31 @@ bool OwncloudPropagator::check_neon_session() return isOk; } -bool OwncloudPropagator::updateErrorFromSession(int neon_code) +bool OwncloudPropagator::updateErrorFromSession(int neon_code, ne_request *req) { bool re = false; if( neon_code != NE_OK ) { - qDebug("Neon error code was %d", neon_code); - } + qDebug("Neon error code was %d", neon_code); + } switch(neon_code) { case NE_OK: /* Success, but still the possiblity of problems */ - if( check_neon_session() ) { - re = true; + if( req != NULL ) { + const ne_status *status = ne_get_status(req); + if( status ) { + if( status->klass != 2 ) { + _httpStatusCode = status->code; + _errorCode = CSYNC_ERR_HTTP; + _errorString = QString::fromUtf8( status->reason_phrase ); + re = true; + } + } else { + re = true; // can not get the status + } + } else { + // no neon request available. + re = check_neon_session(); } break; case NE_ERROR: /* Generic error; use ne_get_error(session) for message */ diff --git a/src/mirall/owncloudpropagator.h b/src/mirall/owncloudpropagator.h index 6ab2c1321..922807819 100644 --- a/src/mirall/owncloudpropagator.h +++ b/src/mirall/owncloudpropagator.h @@ -15,6 +15,8 @@ #ifndef OWNCLOUDPROPAGATOR_H #define OWNCLOUDPROPAGATOR_H +#include + #include "syncfileitem.h" struct ne_session_s; @@ -41,7 +43,7 @@ class OwncloudPropagator { void updateMTimeAndETag(const char *uri, time_t); /* fetch the error code and string from the session */ - bool updateErrorFromSession(int neon_code = 0); + bool updateErrorFromSession(int neon_code = 0, ne_request *req = NULL); public: diff --git a/src/mirall/syncfileitem.h b/src/mirall/syncfileitem.h index 2c534669a..2edd94d58 100644 --- a/src/mirall/syncfileitem.h +++ b/src/mirall/syncfileitem.h @@ -37,6 +37,11 @@ public: Direction _dir; bool _isDirectory; time_t _modtime; + + QString _errorString; + QString _errorDetail; + int _httpCode; + };