Exception handling inside tag_invoke customizations
Author: maxbachmannCreated Sep 13, 2026Updated Sep 15, 2026
Labelshelp wanted
As far as I can tell you are allowed to throw exceptions inside tag invoke customizations to propagate errors instead of forwarding error codes. At least the appendable container customization only removes default constructed values in case errors get propagated via the error code.
template <concepts::appendable_containers T, typename ValT>
error_code tag_invoke(deserialize_tag, ValT &val, T &out) noexcept(false) {
using value_type = typename std::remove_cvref_t<T>::value_type;
static_assert(
deserializable<value_type, ValT>,
"The specified type inside the container must itself be deserializable");
static_assert(
std::is_default_constructible_v<value_type>,
"The specified type inside the container must default constructible.");
arm64::ondemand::array arr;
if constexpr (std::is_same_v<std::remove_cvref_t<ValT>, arm64::ondemand::array>) {
arr = val;
} else {
SIMDJSON_TRY(val.get_array().get(arr));
}
for (auto v : arr) {
if constexpr (concepts::returns_reference<T>) {
if (auto const err = v.get<value_type>().get(concepts::emplace_one(out));
err) {
// If an error occurs, the empty element that we just inserted gets
// removed. We're not using a temp variable because if T is a heavy
// type, we want the valid path to be the fast path and the slow path be
// the path that has errors in it.
if constexpr (requires { out.pop_back(); }) {
static_cast<void>(out.pop_back());
}
return err;
}
} else {
value_type temp;
if (auto const err = v.get<value_type>().get(temp); err) {
return err;
}
concepts::emplace_one(out, std::move(temp));
}
}
return SUCCESS;
}Is this an accepted limitation of customizations or something that should somehow be changed?
Source: simdjson/simdjson