Add sysrepo error handling
Change-Id: I810de1afd0ad6161a18903f816e19db28ed9edf1
diff --git a/src/sysrepo_access.cpp b/src/sysrepo_access.cpp
index 4e1ab4b..16dfab5 100644
--- a/src/sysrepo_access.cpp
+++ b/src/sysrepo_access.cpp
@@ -72,7 +72,11 @@
: m_connection(new sysrepo::Connection(appname.c_str()))
, m_schema(new YangSchema())
{
- m_session = std::make_shared<sysrepo::Session>(m_connection);
+ try {
+ m_session = std::make_shared<sysrepo::Session>(m_connection);
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
+ }
m_schema->registerModuleCallback([this](const char* moduleName, const char* revision, const char* submodule) {
return fetchSchema(moduleName, revision, submodule);
});
@@ -95,57 +99,94 @@
}
};
- if (path == "/") {
- // Sysrepo doesn't have a root node ("/"), so we take all top-level nodes from all schemas
- auto schemas = m_session->list_schemas();
- for (unsigned int i = 0; i < schemas->schema_cnt(); i++) {
- fillMap(m_session->get_items(("/"s + schemas->schema(i)->module_name() + ":*//.").c_str()));
+ try {
+ if (path == "/") {
+ // Sysrepo doesn't have a root node ("/"), so we take all top-level nodes from all schemas
+ auto schemas = m_session->list_schemas();
+ for (unsigned int i = 0; i < schemas->schema_cnt(); i++) {
+ fillMap(m_session->get_items(("/"s + schemas->schema(i)->module_name() + ":*//.").c_str()));
+ }
+ } else {
+ fillMap(m_session->get_items((path + "//.").c_str()));
}
- } else {
- fillMap(m_session->get_items((path + "//.").c_str()));
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
}
-
return res;
}
void SysrepoAccess::setLeaf(const std::string& path, leaf_data_ value)
{
- m_session->set_item(path.c_str(), boost::apply_visitor(valFromValue(), value));
+ try {
+ m_session->set_item(path.c_str(), boost::apply_visitor(valFromValue(), value));
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
+ }
}
void SysrepoAccess::createPresenceContainer(const std::string& path)
{
- m_session->set_item(path.c_str());
+ try {
+ m_session->set_item(path.c_str());
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
+ }
}
void SysrepoAccess::deletePresenceContainer(const std::string& path)
{
- m_session->delete_item(path.c_str());
+ try {
+ m_session->delete_item(path.c_str());
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
+ }
}
void SysrepoAccess::createListInstance(const std::string& path)
{
- m_session->set_item(path.c_str());
+ try {
+ m_session->set_item(path.c_str());
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
+ }
}
void SysrepoAccess::deleteListInstance(const std::string& path)
{
- m_session->delete_item(path.c_str());
+ try {
+ m_session->delete_item(path.c_str());
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
+ }
}
void SysrepoAccess::commitChanges()
{
- m_session->commit();
+ try {
+ m_session->commit();
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
+ }
}
void SysrepoAccess::discardChanges()
{
- m_session->discard_changes();
+ try {
+ m_session->discard_changes();
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
+ }
}
std::string SysrepoAccess::fetchSchema(const char* module, const char* revision, const char* submodule)
{
- auto schema = m_session->get_schema(module, revision, submodule, SR_SCHEMA_YANG); // FIXME: maybe we should use get_submodule_schema for submodules?
+ std::string schema;
+ try {
+ schema = m_session->get_schema(module, revision, submodule, SR_SCHEMA_YANG); // FIXME: maybe we should use get_submodule_schema for submodules?
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
+ }
+
if (schema.empty())
throw std::runtime_error(std::string("Module ") + module + " not available");
@@ -155,7 +196,12 @@
std::vector<std::string> SysrepoAccess::listImplementedSchemas()
{
std::vector<std::string> res;
- auto schemas = m_session->list_schemas();
+ std::shared_ptr<sysrepo::Yang_Schemas> schemas;
+ try {
+ schemas = m_session->list_schemas();
+ } catch (sysrepo::sysrepo_exception& ex) {
+ reportErrors();
+ }
for (unsigned int i = 0; i < schemas->schema_cnt(); i++) {
auto schema = schemas->schema(i);
if (schema->implemented())
@@ -168,3 +214,21 @@
{
return m_schema;
}
+
+[[noreturn]] void SysrepoAccess::reportErrors()
+{
+ // I only use get_last_errors to get error info, since the error code from
+ // sysrepo_exception doesn't really give any meaningful information. For
+ // example an "invalid argument" error could mean a node isn't enabled, or
+ // it could mean something totally different and there is no documentation
+ // for that, so it's better to just use the message sysrepo gives me.
+ auto srErrors = m_session->get_last_errors();
+ std::vector<DatastoreError> res;
+
+ for (size_t i = 0; i < srErrors->error_cnt(); i++) {
+ auto error = srErrors->error(i);
+ res.emplace_back(error->message(), error->xpath() ? std::optional<std::string>{error->xpath()} : std::nullopt);
+ }
+
+ throw DatastoreException(res);
+}