+-------------------------------------------------------------------
+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
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"; }
};
- 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; }
}
- 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;
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();
+ }
}
snapshot.description = description;
snapshot.info_modified = true;
- snapshot.createFilesystemSnapshot();
-
- return entries.insert(entries.end(), snapshot);
+ return createHelper(snapshot);
}
snapshot.description = description;
snapshot.info_modified = true;
- snapshot.createFilesystemSnapshot();
-
- return entries.insert(entries.end(), snapshot);
+ return createHelper(snapshot);
}
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);
}
#include <list>
#include <map>
+#include "snapper/Exception.h"
+
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"; }
void setUserdata(const map<string, string>& userdata);
map<string, string> getUserdata() const { return userdata; }
- bool flushInfo();
+ void flushInfo();
string infoDir() const;
string snapshotDir() const;
bool info_modified;
- bool writeInfo() const;
+ void writeInfo() const;
void createFilesystemSnapshot() const;
void deleteFilesystemSnapshot() const;
iterator createPreSnapshot(string description);
iterator createPostSnapshot(const_iterator pre);
+ iterator createHelper(Snapshot& snapshot);
+
void deleteSnapshot(iterator snapshot);
unsigned int nextNumber();
~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); }
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);
}