From: Arvin Schnell Date: Tue, 20 Sep 2011 10:22:24 +0000 (+0200) Subject: - improved error handling (bnc#718914) X-Git-Tag: v0.1.3~285 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=e64f4f2ae01db89d0a41f1e1010dd206e12eaa21;p=thirdparty%2Fsnapper.git - improved error handling (bnc#718914) --- diff --git a/package/snapper.changes b/package/snapper.changes index 0cb777a8..3c85048e 100644 --- a/package/snapper.changes +++ b/package/snapper.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Sep 20 11:05:47 CEST 2011 - aschnell@suse.de + +- improved error handling (bnc#718914) + ------------------------------------------------------------------- Thu Sep 15 16:44:26 CEST 2011 - aschnell@suse.de diff --git a/snapper/Exception.h b/snapper/Exception.h index e63ca97d..14eb95c0 100644 --- a/snapper/Exception.h +++ b/snapper/Exception.h @@ -30,26 +30,33 @@ namespace snapper { - struct FileNotFoundException : public std::exception + struct SnapperException : public std::exception + { + explicit SnapperException() throw() {} + virtual const char* what() const throw() { return "generic snapper exception"; } + }; + + + struct FileNotFoundException : public SnapperException { explicit FileNotFoundException() throw() {} virtual const char* what() const throw() { return "file not found"; } }; - struct IllegalSnapshotException : public std::exception + struct IllegalSnapshotException : public SnapperException { explicit IllegalSnapshotException() throw() {} virtual const char* what() const throw() { return "illegal snapshot"; } }; - struct LogicErrorException : public std::exception + struct LogicErrorException : public SnapperException { explicit LogicErrorException() throw() {} virtual const char* what() const throw() { return "logic error"; } }; - struct IOErrorException : public std::exception + struct IOErrorException : public SnapperException { explicit IOErrorException() throw() {} virtual const char* what() const throw() { return "IO error"; } diff --git a/snapper/Snapper.h b/snapper/Snapper.h index 88a5e927..91a44d4f 100644 --- a/snapper/Snapper.h +++ b/snapper/Snapper.h @@ -75,32 +75,32 @@ namespace snapper }; - struct ConfigNotFoundException : public std::exception + struct ConfigNotFoundException : public SnapperException { explicit ConfigNotFoundException() throw() {} virtual const char* what() const throw() { return "config not found"; } }; - struct InvalidConfigException : public std::exception + struct InvalidConfigException : public SnapperException { explicit InvalidConfigException() throw() {} virtual const char* what() const throw() { return "invalid config"; } }; - struct InvalidUserdataException : public std::exception + struct InvalidUserdataException : public SnapperException { explicit InvalidUserdataException() throw() {} virtual const char* what() const throw() { return "invalid userdata"; } }; - struct ListConfigsFailedException : public std::exception + struct ListConfigsFailedException : public SnapperException { explicit ListConfigsFailedException(const char* msg) throw() : msg(msg) {} virtual const char* what() const throw() { return msg; } const char* msg; }; - struct AddConfigFailedException : public std::exception + struct AddConfigFailedException : public SnapperException { explicit AddConfigFailedException(const char* msg) throw() : msg(msg) {} virtual const char* what() const throw() { return msg; } diff --git a/snapper/Snapshot.cc b/snapper/Snapshot.cc index ffac62f2..dff35b07 100644 --- a/snapper/Snapshot.cc +++ b/snapper/Snapshot.cc @@ -337,21 +337,18 @@ namespace snapper } - bool + void Snapshot::flushInfo() { if (!info_modified) - return true; - - if (!writeInfo()) - return false; + return; + writeInfo(); info_modified = false; - return true; } - bool + void Snapshot::writeInfo() const { XmlFile xml; @@ -380,9 +377,19 @@ namespace snapper setChildValue(userdata_node, "value", it->second); } - xml.save(infoDir() + "/info.xml"); + if (!xml.save(infoDir() + "/info.xml.tmp")) + { + y2err("saving info.xml failed infoDir: " << infoDir() << " errno: << " << errno << + " (" << strerror(errno) << ")"); + throw IOErrorException(); + } - return true; + if (rename(string(infoDir() + "/info.xml.tmp").c_str(), string(infoDir() + "/info.xml").c_str()) != 0) + { + y2err("rename info.xml failed infoDir: " << infoDir() << " errno: << " << errno << + " (" << strerror(errno) << ")"); + throw IOErrorException(); + } } @@ -434,9 +441,7 @@ namespace snapper snapshot.description = description; snapshot.info_modified = true; - snapshot.createFilesystemSnapshot(); - - return entries.insert(entries.end(), snapshot); + return createHelper(snapshot); } @@ -447,9 +452,7 @@ namespace snapper snapshot.description = description; snapshot.info_modified = true; - snapshot.createFilesystemSnapshot(); - - return entries.insert(entries.end(), snapshot); + return createHelper(snapshot); } @@ -463,7 +466,33 @@ namespace snapper snapshot.pre_num = pre->getNum(); snapshot.info_modified = true; - snapshot.createFilesystemSnapshot(); + return createHelper(snapshot); + } + + + Snapshots::iterator + Snapshots::createHelper(Snapshot& snapshot) + { + try + { + snapshot.createFilesystemSnapshot(); + } + catch (const CreateSnapshotFailedException& e) + { + rmdir(snapshot.infoDir().c_str()); + throw; + } + + try + { + snapshot.flushInfo(); + } + catch (const IOErrorException& e) + { + snapshot.deleteFilesystemSnapshot(); + rmdir(snapshot.infoDir().c_str()); + throw; + } return entries.insert(entries.end(), snapshot); } diff --git a/snapper/Snapshot.h b/snapper/Snapshot.h index b41fcfea..769c0bdc 100644 --- a/snapper/Snapshot.h +++ b/snapper/Snapshot.h @@ -29,6 +29,8 @@ #include #include +#include "snapper/Exception.h" + namespace snapper { @@ -43,32 +45,32 @@ namespace snapper enum SnapshotType { SINGLE, PRE, POST }; - struct CreateSnapshotFailedException : public std::exception + struct CreateSnapshotFailedException : public SnapperException { explicit CreateSnapshotFailedException() throw() {} virtual const char* what() const throw() { return "create snapshot failed"; } }; - struct DeleteSnapshotFailedException : public std::exception + struct DeleteSnapshotFailedException : public SnapperException { explicit DeleteSnapshotFailedException() throw() {} virtual const char* what() const throw() { return "delete snapshot failed"; } }; - struct IsSnapshotMountedFailedException : public std::exception + struct IsSnapshotMountedFailedException : public SnapperException { explicit IsSnapshotMountedFailedException() throw() {} virtual const char* what() const throw() { return "is snapshot mounted failed"; } }; - struct MountSnapshotFailedException : public std::exception + struct MountSnapshotFailedException : public SnapperException { explicit MountSnapshotFailedException() throw() {} virtual const char* what() const throw() { return "mount snapshot failed"; } }; - struct UmountSnapshotFailedException : public std::exception + struct UmountSnapshotFailedException : public SnapperException { explicit UmountSnapshotFailedException() throw() {} virtual const char* what() const throw() { return "umount snapshot failed"; } @@ -103,7 +105,7 @@ namespace snapper void setUserdata(const map& userdata); map getUserdata() const { return userdata; } - bool flushInfo(); + void flushInfo(); string infoDir() const; string snapshotDir() const; @@ -133,7 +135,7 @@ namespace snapper bool info_modified; - bool writeInfo() const; + void writeInfo() const; void createFilesystemSnapshot() const; void deleteFilesystemSnapshot() const; @@ -190,6 +192,8 @@ namespace snapper iterator createPreSnapshot(string description); iterator createPostSnapshot(const_iterator pre); + iterator createHelper(Snapshot& snapshot); + void deleteSnapshot(iterator snapshot); unsigned int nextNumber(); diff --git a/snapper/XmlFile.h b/snapper/XmlFile.h index c148952d..3c8d9e86 100644 --- a/snapper/XmlFile.h +++ b/snapper/XmlFile.h @@ -48,7 +48,7 @@ namespace snapper ~XmlFile(); bool save(const string& filename) - { return xmlSaveFormatFile(filename.c_str(), doc, 1); } + { return xmlSaveFormatFile(filename.c_str(), doc, 1) != -1; } void setRootElement(xmlNode* node) { xmlDocSetRootElement(doc, node); } diff --git a/tools/snapper.cc b/tools/snapper.cc index cba5b3fa..547fb0f4 100644 --- a/tools/snapper.cc +++ b/tools/snapper.cc @@ -1136,7 +1136,17 @@ main(int argc, char** argv) sh->setUndoCallback(&undo_callback_impl); } - (*cmd->second)(); + try + { + (*cmd->second)(); + } + catch (const SnapperException& e) + { + y2err("caught final exception"); + cerr << sformat(_("Command failed (%s). See log for more information."), + e.what()) << endl; + exit(EXIT_FAILURE); + } deleteSnapper(sh); }