aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLexi Winter <lexi@hemlock.eden.le-fay.org>2025-03-27 12:25:30 +0000
committerLexi Winter <lexi@hemlock.eden.le-fay.org>2025-03-27 12:25:30 +0000
commit053d3c66451e16eb3022d105beaf4a0efe3cf771 (patch)
tree8bd48c0917b4e01a84728102e37cade68de6d807
parent84b9e774ceaa5ff89854415bcba430dacd04f376 (diff)
downloadlibnvxx-053d3c66451e16eb3022d105beaf4a0efe3cf771.tar.gz
libnvxx-053d3c66451e16eb3022d105beaf4a0efe3cf771.tar.bz2
clean up error handling a little
-rw-r--r--libnvxx/const_nv_list.cc66
-rw-r--r--libnvxx/nv_list.cc54
-rw-r--r--libnvxx/nvxx.323
3 files changed, 122 insertions, 21 deletions
diff --git a/libnvxx/const_nv_list.cc b/libnvxx/const_nv_list.cc
index 60605fa..a2306e9 100644
--- a/libnvxx/const_nv_list.cc
+++ b/libnvxx/const_nv_list.cc
@@ -62,32 +62,36 @@ namespace __detail {
std::error_code
__const_nv_list::error() const noexcept
{
- if (auto const err = nvlist_error(__m_nv); err != 0)
+ if (auto const err = ::nvlist_error(__m_nv); err != 0)
return (std::make_error_code(std::errc(err)));
return {};
}
bool
-__const_nv_list::exists(std::string_view key) const
+__const_nv_list::exists_type(std::string_view key, int type) const
{
- return (::nvlist_exists(__m_nv, std::string(key).c_str()));
+ __throw_if_error();
+ return (::nvlist_exists_type(__m_nv, std::string(key).c_str(), type));
}
bool
-__const_nv_list::exists_type(std::string_view key, int type) const
+__const_nv_list::exists(std::string_view key) const
{
- return (::nvlist_exists_type(__m_nv, std::string(key).c_str(), type));
+ return exists_type(key, NV_TYPE_NONE);
}
+
bool
__const_nv_list::empty() const noexcept
{
+ __throw_if_error();
return (::nvlist_empty(__m_nv));
}
int
__const_nv_list::flags() const noexcept
{
+ __throw_if_error();
return (::nvlist_flags(__m_nv));
}
@@ -134,6 +138,8 @@ __const_nv_list::packed_size() const noexcept
std::vector<std::byte>
__const_nv_list::pack() const
{
+ __throw_if_error();
+
auto size = std::size_t{};
if (auto *data = nvlist_pack(__m_nv, &size); data != nullptr) {
@@ -151,7 +157,7 @@ __const_nv_list::pack() const
bool
__const_nv_list::exists_null(std::string_view key) const
{
- return (::nvlist_exists_null(__m_nv, std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_NULL));
}
/*
@@ -161,12 +167,14 @@ __const_nv_list::exists_null(std::string_view key) const
bool
__const_nv_list::exists_bool(std::string_view key) const
{
- return (::nvlist_exists_bool(__m_nv, std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_BOOL));
}
bool
__const_nv_list::get_bool(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_bool(__m_nv, skey.c_str()))
@@ -178,12 +186,14 @@ __const_nv_list::get_bool(std::string_view key) const
bool
__const_nv_list::exists_bool_array(std::string_view key) const
{
- return (::nvlist_exists_bool_array(__m_nv, std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_BOOL_ARRAY));
}
std::span<bool const>
__const_nv_list::get_bool_array(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_bool_array(__m_nv, skey.c_str()))
@@ -201,12 +211,14 @@ __const_nv_list::get_bool_array(std::string_view key) const
bool
__const_nv_list::exists_number(std::string_view key) const
{
- return (::nvlist_exists_number(__m_nv, std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_NUMBER));
}
std::uint64_t
__const_nv_list::get_number(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_number(__m_nv, skey.c_str()))
@@ -218,13 +230,14 @@ __const_nv_list::get_number(std::string_view key) const
bool
__const_nv_list::exists_number_array(std::string_view key) const
{
- return (::nvlist_exists_number_array(__m_nv,
- std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_NUMBER_ARRAY));
}
std::span<std::uint64_t const>
__const_nv_list::get_number_array(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_number_array(__m_nv, skey.c_str()))
@@ -242,12 +255,14 @@ __const_nv_list::get_number_array(std::string_view key) const
bool
__const_nv_list::exists_string(std::string_view key) const
{
- return (::nvlist_exists_string(__m_nv, std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_STRING));
}
std::string_view
__const_nv_list::get_string(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_string(__m_nv, skey.c_str()))
@@ -259,13 +274,14 @@ __const_nv_list::get_string(std::string_view key) const
bool
__const_nv_list::exists_string_array(std::string_view key) const
{
- return (::nvlist_exists_string_array(__m_nv,
- std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_STRING_ARRAY));
}
std::vector<std::string_view>
__const_nv_list::get_string_array(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_string_array(__m_nv, skey.c_str()))
@@ -285,12 +301,14 @@ __const_nv_list::get_string_array(std::string_view key) const
bool
__const_nv_list::exists_nvlist(std::string_view key) const
{
- return (::nvlist_exists_nvlist(__m_nv, std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_NVLIST));
}
const_nv_list
__const_nv_list::get_nvlist(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_nvlist(__m_nv, skey.c_str()))
@@ -303,13 +321,14 @@ __const_nv_list::get_nvlist(std::string_view key) const
bool
__const_nv_list::exists_nvlist_array(std::string_view key) const
{
- return (::nvlist_exists_nvlist_array(__m_nv,
- std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_NVLIST_ARRAY));
}
std::vector<const_nv_list>
__const_nv_list::get_nvlist_array(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_nvlist_array(__m_nv, skey.c_str()))
@@ -328,6 +347,8 @@ __const_nv_list::get_nvlist_array(std::string_view key) const
int
__const_nv_list::get_descriptor(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_descriptor(__m_nv, skey.c_str()))
@@ -339,6 +360,8 @@ __const_nv_list::get_descriptor(std::string_view key) const
std::span<int const>
__const_nv_list::get_descriptor_array(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_descriptor_array(__m_nv, skey.c_str()))
@@ -353,14 +376,13 @@ __const_nv_list::get_descriptor_array(std::string_view key) const
bool
__const_nv_list::exists_descriptor(std::string_view key) const
{
- return (::nvlist_exists_descriptor(__m_nv, std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_DESCRIPTOR));
}
bool
__const_nv_list::exists_descriptor_array(std::string_view key) const
{
- return (::nvlist_exists_descriptor_array(__m_nv,
- std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_DESCRIPTOR_ARRAY));
}
/*
@@ -370,12 +392,14 @@ __const_nv_list::exists_descriptor_array(std::string_view key) const
bool
__const_nv_list::exists_binary(std::string_view key) const
{
- return (::nvlist_exists_binary(__m_nv, std::string(key).c_str()));
+ return (exists_type(key, NV_TYPE_BINARY));
}
std::span<std::byte const>
__const_nv_list::get_binary(std::string_view key) const
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_binary(__m_nv, skey.c_str()))
diff --git a/libnvxx/nv_list.cc b/libnvxx/nv_list.cc
index c66c08f..c2b9372 100644
--- a/libnvxx/nv_list.cc
+++ b/libnvxx/nv_list.cc
@@ -144,6 +144,8 @@ namespace __detail {
void
__nv_list::set_error(int error) noexcept
{
+ // nvlist does not allow changing an existing error state
+ __throw_if_error();
::nvlist_set_error(__m_nv, error);
}
@@ -232,6 +234,8 @@ __nv_list::add_bool(std::string_view key, bool value)
bool
__nv_list::take_bool(std::string_view key)
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_bool(__m_nv, skey.c_str()))
@@ -249,6 +253,8 @@ __nv_list::free_bool(std::string_view key)
std::vector<bool>
__nv_list::take_bool_array(std::string_view key)
{
+ __throw_if_error();
+
auto nitems = std::size_t{};
auto ptr = __ptr_guard(::nvlist_take_bool_array(
__m_nv, std::string(key).c_str(), &nitems));
@@ -283,6 +289,8 @@ __nv_list::add_bool_array(std::string_view key,
void
__nv_list::move_bool_array(std::string_view key, std::span<bool> value)
{
+ __throw_if_error();
+
::nvlist_move_bool_array(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
std::ranges::size(value));
@@ -291,6 +299,8 @@ __nv_list::move_bool_array(std::string_view key, std::span<bool> value)
void
__nv_list::append_bool_array(std::string_view key, bool value)
{
+ __throw_if_error();
+
::nvlist_append_bool_array(__m_nv, std::string(key).c_str(), value);
}
@@ -329,6 +339,8 @@ __nv_list::add_number(std::string_view key, std::uint64_t value)
std::uint64_t
__nv_list::take_number(std::string_view key)
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_number(__m_nv, skey.c_str()))
@@ -346,6 +358,8 @@ __nv_list::free_number(std::string_view key)
std::vector<std::uint64_t>
__nv_list::take_number_array(std::string_view key)
{
+ __throw_if_error();
+
auto nitems = std::size_t{};
auto ptr = __ptr_guard(
::nvlist_take_number_array(__m_nv,
@@ -383,6 +397,8 @@ void
__nv_list::move_number_array(std::string_view key,
std::span<std::uint64_t> value)
{
+ __throw_if_error();
+
::nvlist_move_number_array(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
std::ranges::size(value));
@@ -391,6 +407,8 @@ __nv_list::move_number_array(std::string_view key,
void
__nv_list::append_number_array(std::string_view key, std::uint64_t value)
{
+ __throw_if_error();
+
::nvlist_append_number_array(__m_nv, std::string(key).c_str(), value);
}
@@ -429,12 +447,16 @@ __nv_list::add_string(std::string_view key, std::string_view value)
void
__nv_list::move_string(std::string_view key, char *value)
{
+ __throw_if_error();
+
::nvlist_move_string(__m_nv, std::string(key).c_str(), value);
}
std::string
__nv_list::take_string(std::string_view key)
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_string(__m_nv, skey.c_str()))
@@ -488,6 +510,8 @@ void
__nv_list::move_string_array(std::string_view key,
std::span<char *> value)
{
+ __throw_if_error();
+
::nvlist_move_string_array(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
std::ranges::size(value));
@@ -496,6 +520,8 @@ __nv_list::move_string_array(std::string_view key,
void
__nv_list::append_string_array(std::string_view key, std::string_view value)
{
+ __throw_if_error();
+
::nvlist_append_string_array(__m_nv,
std::string(key).c_str(),
std::string(value).c_str());
@@ -504,6 +530,8 @@ __nv_list::append_string_array(std::string_view key, std::string_view value)
std::vector<std::string>
__nv_list::take_string_array(std::string_view key)
{
+ __throw_if_error();
+
auto nitems = std::size_t{};
auto *data = nvlist_take_string_array(__m_nv, std::string(key).c_str(),
&nitems);
@@ -547,6 +575,8 @@ __nv_list::add_nvlist(std::string_view key, const_nv_list const &other)
void
__nv_list::move_nvlist(std::string_view key, nv_list &&value)
{
+ __throw_if_error();
+
::nvlist_move_nvlist(__m_nv, std::string(key).c_str(),
std::exchange(value.__m_nv, nullptr));
}
@@ -554,12 +584,16 @@ __nv_list::move_nvlist(std::string_view key, nv_list &&value)
void
__nv_list::move_nvlist(std::string_view key, ::nvlist_t *value)
{
+ __throw_if_error();
+
::nvlist_move_nvlist(__m_nv, std::string(key).c_str(), value);
}
nv_list
__nv_list::take_nvlist(std::string_view key)
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_nvlist(__m_nv, skey.c_str()))
@@ -635,6 +669,8 @@ void
__nv_list::move_nvlist_array(std::string_view key,
std::span<::nvlist_t *> value)
{
+ __throw_if_error();
+
::nvlist_move_nvlist_array(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
std::ranges::size(value));
@@ -644,6 +680,8 @@ void
__nv_list::append_nvlist_array(std::string_view key,
const_nv_list const &value)
{
+ __throw_if_error();
+
::nvlist_append_nvlist_array(__m_nv, std::string(key).c_str(),
value.__m_nv);
}
@@ -651,6 +689,8 @@ __nv_list::append_nvlist_array(std::string_view key,
std::vector<nv_list>
__nv_list::take_nvlist_array(std::string_view key)
{
+ __throw_if_error();
+
auto nitems = std::size_t{};
auto ptr = __ptr_guard(
::nvlist_take_nvlist_array(__m_nv,
@@ -673,6 +713,8 @@ __nv_list::free_nvlist_array(std::string_view key)
int
__nv_list::take_descriptor(std::string_view key)
{
+ __throw_if_error();
+
return (::nvlist_take_descriptor(__m_nv, std::string(key).c_str()));
}
@@ -701,6 +743,8 @@ __nv_list::add_descriptor(std::string_view key, int value)
void
__nv_list::move_descriptor(std::string_view key, int value)
{
+ __throw_if_error();
+
::nvlist_move_descriptor(__m_nv, std::string(key).c_str(), value);
}
@@ -713,6 +757,8 @@ __nv_list::free_descriptor(std::string_view key)
void
__nv_list::append_descriptor_array(std::string_view key, int value)
{
+ __throw_if_error();
+
::nvlist_append_descriptor_array(__m_nv,
std::string(key).c_str(),
value);
@@ -746,6 +792,8 @@ __nv_list::add_descriptor_array(std::string_view key,
void
__nv_list::move_descriptor_array(std::string_view key, std::span<int> value)
{
+ __throw_if_error();
+
::nvlist_add_descriptor_array(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
std::ranges::size(value));
@@ -760,6 +808,8 @@ __nv_list::free_descriptor_array(std::string_view key)
std::vector<int>
__nv_list::take_descriptor_array(std::string_view key)
{
+ __throw_if_error();
+
auto nitems = std::size_t{};
auto ptr = __ptr_guard(
::nvlist_take_descriptor_array(__m_nv,
@@ -799,6 +849,8 @@ __nv_list::add_binary(std::string_view key, std::span<std::byte const> value)
void
__nv_list::move_binary(std::string_view key, std::span<std::byte> value)
{
+ __throw_if_error();
+
::nvlist_move_binary(__m_nv, std::string(key).c_str(),
std::ranges::data(value),
std::ranges::size(value));
@@ -813,6 +865,8 @@ __nv_list::free_binary(std::string_view key)
std::vector<std::byte>
__nv_list::take_binary(std::string_view key)
{
+ __throw_if_error();
+
auto skey = std::string(key);
if (!::nvlist_exists_binary(__m_nv, skey.c_str()))
diff --git a/libnvxx/nvxx.3 b/libnvxx/nvxx.3
index 19b572d..96cd514 100644
--- a/libnvxx/nvxx.3
+++ b/libnvxx/nvxx.3
@@ -294,6 +294,25 @@ nvlist.
Thrown when an attempt is made to add a key to an nvlist when a key of the same
name is already present, and the list does permit duplicates.
.El
+.Pp
+The underlying C library has the concept of an error state, an internal flag
+on the nvlist which indicates an error has previously occurred.
+Once an nvlist is in the error state, no operations on the nvlist are
+permitted.
+This error state cannot be cleared.
+.Pp
+The C++ library will prohibit any operation which would result in the error
+state being set on the underlying nvlist, and such operations will throw an
+exception instead.
+If the underlying nvlist does enter the error state (for example, because the
+nvlist was manually modified using the
+.Fn ptr
+member function), then all subsequent operations will fail and throw the
+.Vt nv_error_state
+exception.
+The
+.Va nv_error_state::error
+member variable may then be used to determine which specific error occurred.
.Sh CONST_NV_LIST OPERATIONS
The
.Fn dump
@@ -338,6 +357,10 @@ member function serializes the nvlist to a byte stream and returns it.
The byte stream can later be passed to
.Fn nv_list::unpack
to turn it back into an nvlist.
+If the pack operation fails (for example, due to an out-of-memory condition),
+then an exception of type
+.Vt std::system_error
+will be thrown.
.Pp
The
.Fn packed_size