Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make exceptions thrown by nested collections more consistent #6875

Merged
merged 1 commit into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions src/realm/dictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,18 @@ bool Dictionary::is_null(size_t ndx) const
Mixed Dictionary::get_any(size_t ndx) const
{
// Note: `size()` calls `update_if_needed()`.
CollectionBase::validate_index("get_any()", ndx, size());
auto current_size = size();
ensure_attached();
CollectionBase::validate_index("get_any()", ndx, current_size);
return do_get(ndx);
}

std::pair<Mixed, Mixed> Dictionary::get_pair(size_t ndx) const
{
// Note: `size()` calls `update_if_needed()`.
CollectionBase::validate_index("get_pair()", ndx, size());
auto current_size = size();
ensure_attached();
CollectionBase::validate_index("get_pair()", ndx, current_size);
return do_get_pair(ndx);
}

Expand Down Expand Up @@ -467,6 +471,7 @@ Mixed Dictionary::get(Mixed key) const
if (auto opt_val = try_get(key)) {
return *opt_val;
}
ensure_attached();
throw KeyNotFound("Dictionary::get");
}

Expand Down Expand Up @@ -664,9 +669,15 @@ UpdateStatus Dictionary::update_if_needed_with_status() const noexcept
void Dictionary::ensure_created()
{
if (Base::should_update() || !(m_dictionary_top && m_dictionary_top->is_attached())) {
if (!init_from_parent(true)) {
throw IllegalOperation("This is an ex-dictionary");
}
init_from_parent(true);
ensure_attached();
}
}

void Dictionary::ensure_attached() const
{
if (!m_dictionary_top) {
throw IllegalOperation("This is an ex-dictionary");
}
}

Expand All @@ -690,6 +701,7 @@ bool Dictionary::try_erase(Mixed key)
void Dictionary::erase(Mixed key)
{
if (!try_erase(key)) {
ensure_attached();
throw KeyNotFound(util::format("Cannot remove key %1 from dictionary: key not found", key));
}
}
Expand Down
1 change: 1 addition & 0 deletions src/realm/dictionary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ class Dictionary final : public CollectionBaseImpl<DictionaryBase>, public Colle
void do_accumulate(size_t* return_ndx, AggregateType& agg) const;

void ensure_created();
void ensure_attached() const;
inline bool update() const
{
return update_if_needed_with_status() != UpdateStatus::Detached;
Expand Down
12 changes: 9 additions & 3 deletions src/realm/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,9 +479,8 @@ class Lst<Mixed> final : public CollectionBaseImpl<LstBase>, public CollectionPa
void ensure_created()
{
if (Base::should_update() || !(m_tree && m_tree->is_attached())) {
if (!init_from_parent(true)) {
throw IllegalOperation("This is an ex-list");
}
init_from_parent(true);
ensure_attached();
Base::update_content_version();
}
}
Expand Down Expand Up @@ -621,9 +620,16 @@ class Lst<Mixed> final : public CollectionBaseImpl<LstBase>, public CollectionPa
return Mixed{};
return value;
}
void ensure_attached() const
{
if (!m_tree->is_attached()) {
throw IllegalOperation("This is an ex-list");
}
}
Mixed do_get(size_t ndx, const char* msg) const
{
const auto current_size = size();
ensure_attached();
CollectionBase::validate_index(msg, ndx, current_size);

return unresolved_to_null(m_tree->get(ndx));
Expand Down
13 changes: 11 additions & 2 deletions test/test_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,20 +883,29 @@ TEST(List_Nested_InMixed)
]
}
*/
std::string message;
CHECK_EQUAL(list2->get(1), Mixed("Hello"));
tr->promote_to_write();
list2->remove(1);
CHECK_EQUAL(dict2->get("Hello"), Mixed("World"));
obj.set(col_any, Mixed());
CHECK_EQUAL(dict->size(), 0);
CHECK_THROW_ANY(dict->insert("Five", 5)); // This dictionary ceased to be
CHECK_THROW_ANY_GET_MESSAGE(dict->insert("Five", 5), message); // This dictionary ceased to be
CHECK_EQUAL(message, "This is an ex-dictionary");
CHECK_THROW_ANY_GET_MESSAGE(dict->get("Five"), message);
CHECK_EQUAL(message, "This is an ex-dictionary");

obj.set_collection(col_any, CollectionType::List);
auto list3 = obj.get_list_ptr<Mixed>(col_any);
list3->add(5);
obj.set(col_any, Mixed());
CHECK_EQUAL(list3->size(), 0);
CHECK_THROW_ANY(list3->add(42));
CHECK_THROW_ANY_GET_MESSAGE(list3->add(42), message);
CHECK_EQUAL(message, "This is an ex-list");
CHECK_THROW_ANY_GET_MESSAGE(list3->insert(5, 42), message);
CHECK_EQUAL(message, "This is an ex-list");
CHECK_THROW_ANY_GET_MESSAGE(list3->get(5), message);
CHECK_EQUAL(message, "This is an ex-list");
tr->verify();
obj.set_json(col_any,
"[{\"Seven\":7, \"Six\":6}, \"Hello\", {\"Points\": [1.25, 4.5, 6.75], \"Hello\": \"World\"}]");
Expand Down
Loading