Improve error handling, add error string to each individual file item.

This commit is contained in:
Klaas Freitag 2013-05-05 11:41:31 +02:00
parent ecaf66db5d
commit 721a8f79ab
5 changed files with 52 additions and 37 deletions

View file

@ -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; QString errStr;
@ -110,7 +110,7 @@ QString CSyncThread::csyncErrorToString( CSYNC_ERROR_CODE err, const char *errSt
case CSYNC_ERR_ACCESS_FAILED: case CSYNC_ERR_ACCESS_FAILED:
errStr = tr("<p>The target directory does not exist.</p><p>Please check the sync setup.</p>"); errStr = tr("<p>The target directory does not exist.</p><p>Please check the sync setup.</p>");
// this is critical. The database has to be removed. // this is critical. The database has to be removed.
emit wipeDb(); // emit wipeDb(); FIXME - what about this?
break; break;
case CSYNC_ERR_REMOTE_CREATE: case CSYNC_ERR_REMOTE_CREATE:
case CSYNC_ERR_REMOTE_STAT: 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 ); errStr = tr("An internal error number %1 happend.").arg( (int) err );
} }
if( errString ) {
errStr += tr("<br/>Backend Message: ")+QString::fromUtf8(errString);
}
return errStr; return errStr;
} }
@ -299,7 +296,11 @@ struct CSyncRunScopeHelper {
void CSyncThread::handleSyncError(CSYNC *ctx, const char *state) { void CSyncThread::handleSyncError(CSYNC *ctx, const char *state) {
CSYNC_ERROR_CODE err = csync_get_error( ctx ); CSYNC_ERROR_CODE err = csync_get_error( ctx );
const char *errMsg = csync_get_error_string( ctx ); const char *errMsg = csync_get_error_string( ctx );
QString errStr = csyncErrorToString(err, errMsg); QString errStr = csyncErrorToString(err);
if( errMsg ) {
errStr += QLatin1String("<br/>");
errStr += QString::fromUtf8(errMsg);
}
qDebug() << " #### ERROR during "<< state << ": " << errStr; qDebug() << " #### ERROR during "<< state << ": " << errStr;
switch (err) { switch (err) {
case CSYNC_ERR_SERVICE_UNAVAILABLE: case CSYNC_ERR_SERVICE_UNAVAILABLE:
@ -384,6 +385,19 @@ void CSyncThread::startSync()
propagator._etag.clear(); // FIXME : set to the right one propagator._etag.clear(); // FIXME : set to the right one
a.instruction = propagator.propagate(item); 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 if (item._isDirectory && item._instruction == CSYNC_INSTRUCTION_REMOVE
&& a.instruction == CSYNC_INSTRUCTION_DELETED) { && a.instruction == CSYNC_INSTRUCTION_DELETED) {
lastDeleted = item._file; lastDeleted = item._file;
@ -400,7 +414,7 @@ void CSyncThread::startSync()
performedActions.insert(item._renameTarget, a); performedActions.insert(item._renameTarget, a);
} }
//TODO record errors and progress; //TODO progress;
} }
// if( csync_propagate(_csync_ctx) < 0 ) { // if( csync_propagate(_csync_ctx) < 0 ) {

View file

@ -46,7 +46,7 @@ public:
CSyncThread(CSYNC *, const QString &localPath, const QString &remotePath); CSyncThread(CSYNC *, const QString &localPath, const QString &remotePath);
~CSyncThread(); ~CSyncThread();
QString csyncErrorToString( CSYNC_ERROR_CODE, const char * ); QString csyncErrorToString(CSYNC_ERROR_CODE) const;
Q_INVOKABLE void startSync(); Q_INVOKABLE void startSync();

View file

@ -26,7 +26,6 @@
#include <neon/ne_basic.h> #include <neon/ne_basic.h>
#include <neon/ne_socket.h> #include <neon/ne_socket.h>
#include <neon/ne_session.h> #include <neon/ne_session.h>
#include <neon/ne_request.h>
#include <neon/ne_props.h> #include <neon/ne_props.h>
#include <neon/ne_auth.h> #include <neon/ne_auth.h>
#include <neon/ne_dates.h> #include <neon/ne_dates.h>
@ -294,18 +293,10 @@ void OwncloudPropagator::updateMTimeAndETag(const char* uri, time_t mtime)
QScopedPointer<ne_request, ScopedPointerHelpers> req(ne_request_create(_session, "HEAD", uri)); QScopedPointer<ne_request, ScopedPointerHelpers> req(ne_request_create(_session, "HEAD", uri));
int neon_stat = ne_request_dispatch(req.data()); int neon_stat = ne_request_dispatch(req.data());
if( neon_stat != NE_OK ) { if( updateErrorFromSession(neon_stat, req.data()) ) {
updateErrorFromSession(neon_stat); // error happend
qDebug() << "Could not issue HEAD request for ETag.";
} else { } 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()); _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_unhook_post_headers( _session, DownloadContext::install_content_reader, &writeCtx );
// ne_set_notifier(_session, 0, 0); // ne_set_notifier(_session, 0, 0);
if( neon_stat != NE_OK ) { if( updateErrorFromSession(neon_stat, req.data() ) ) {
updateErrorFromSession(neon_stat);
qDebug("Error GET: Neon: %d", neon_stat); qDebug("Error GET: Neon: %d", neon_stat);
return CSYNC_INSTRUCTION_ERROR; 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 : "<empty");
if( status->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()); _etag = parseEtag(req.data());
@ -531,7 +512,7 @@ bool OwncloudPropagator::check_neon_session()
return isOk; return isOk;
} }
bool OwncloudPropagator::updateErrorFromSession(int neon_code) bool OwncloudPropagator::updateErrorFromSession(int neon_code, ne_request *req)
{ {
bool re = false; bool re = false;
@ -541,9 +522,22 @@ bool OwncloudPropagator::updateErrorFromSession(int neon_code)
switch(neon_code) { switch(neon_code) {
case NE_OK: /* Success, but still the possiblity of problems */ case NE_OK: /* Success, but still the possiblity of problems */
if( check_neon_session() ) { 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; re = true;
} }
} else {
re = true; // can not get the status
}
} else {
// no neon request available.
re = check_neon_session();
}
break; break;
case NE_ERROR: /* Generic error; use ne_get_error(session) for message */ case NE_ERROR: /* Generic error; use ne_get_error(session) for message */
_errorString = QString::fromUtf8( ne_get_error(_session) ); _errorString = QString::fromUtf8( ne_get_error(_session) );

View file

@ -15,6 +15,8 @@
#ifndef OWNCLOUDPROPAGATOR_H #ifndef OWNCLOUDPROPAGATOR_H
#define OWNCLOUDPROPAGATOR_H #define OWNCLOUDPROPAGATOR_H
#include <neon/ne_request.h>
#include "syncfileitem.h" #include "syncfileitem.h"
struct ne_session_s; struct ne_session_s;
@ -41,7 +43,7 @@ class OwncloudPropagator {
void updateMTimeAndETag(const char *uri, time_t); void updateMTimeAndETag(const char *uri, time_t);
/* fetch the error code and string from the session */ /* 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: public:

View file

@ -37,6 +37,11 @@ public:
Direction _dir; Direction _dir;
bool _isDirectory; bool _isDirectory;
time_t _modtime; time_t _modtime;
QString _errorString;
QString _errorDetail;
int _httpCode;
}; };