avoid nodiscard compiler warnings

We got a lot of the warnings for unchecked Result / tl::expected; let's
handle those.
This commit is contained in:
Dirk-Jan C. Binnema
2026-08-09 18:26:42 +03:00
committed by Seth Ladygo
parent 7e32324ac4
commit 36d45b38af
11 changed files with 82 additions and 29 deletions

View File

@ -429,6 +429,21 @@ public:
return Ok();
}
/**
* Set a new value for some property; unlike set(), merely log a
* warning if that fails. For callers that cannot meaningfully
* handle the error.
*
* @param prop_id property-id
* @param val the new value (of the correct type)
*/
template<Id ID, typename T>
void checked_set(const T& val) {
if (const auto res{set<ID>(val)}; !res)
mu_warning("failed to set config property '{}': {}",
property<ID>().name, res.error());
}
/**
* Is this a read-only Config?
*

View File

@ -162,8 +162,11 @@ ContactsCache::Private::serialize() const
ci.message_date, SepaChar2,
ci.frequency);
}
config_db_.set<Config::Id::Contacts>(s);
dirty_ = 0;
if (const auto res{config_db_.set<Config::Id::Contacts>(s)}; res)
dirty_ = 0;
else
mu_error("failed to serialize contacts: {}",
res.error());
}
ContactsCache::ContactsCache(Config& config_db)

View File

@ -427,7 +427,7 @@ Indexer::Private::scan_worker()
if (!aborted && conf_.scan) {
// Store started time, not ending time, so that next time we run we know to scan
// anything that appeared during our scan.
store_.config().set<Mu::Config::Id::LastIndex>(started_.value());
store_.config().checked_set<Mu::Config::Id::LastIndex>(started_.value());
}
completed_ = ::time({});

View File

@ -30,9 +30,12 @@ Mu::LabelsCache::serialize() const
for (const auto&[label, n]: label_map_)
s += mu_format("{}{}{}\n", label, SepaChar2, n);
config_.set<Config::Id::Labels>(s);
mu_debug("labels: serialized {} change(s)", dirty_);
dirty_ = 0;
if (const auto res{config_.set<Config::Id::Labels>(s)}; res) {
mu_debug("labels: serialized {} change(s)", dirty_);
dirty_ = 0;
} else
mu_warning("labels: fail to store labels: {}",
res.error());
}
Mu::LabelsCache::Map

View File

@ -429,7 +429,10 @@ main (int argc, char *argv[])
Scanner scanner{argv[1], on_path, Mode::MaildirsOnly};
scanner.start();
if (const auto res{scanner.start()}; !res) {
mu_printerrln("scan failed: {}", res.error());
return 1;
}
return 0;
}

View File

@ -141,7 +141,9 @@ struct Server::Private {
if (have_indexer_)
indexer().stop();
if (!tmp_dir_.empty())
remove_directory(tmp_dir_);
if (const auto res{remove_directory(tmp_dir_)}; !res)
mu_warning("failed to remove '{}': {}",
tmp_dir_, res.error());
}
//
// construction helpers
@ -552,13 +554,15 @@ Server::Private::contacts_handler(const Command& cmd)
auto n{0};
auto&& out{make_output_stream()};
mu_print(out, "(");
store().contacts_cache().for_each([&](const Contact& ci) {
const auto res = store().contacts_cache().for_each([&](const Contact& ci) {
if (!match_contact(ci))
return true; // continue
mu_println(out.out(), "{}", quote(ci.display_name()));
++n;
return maxnum == 0 || n < maxnum;
});
if (!res)
mu_warning("contacts: {}", res.error());
mu_print(out, ")");
output(mu_format("(:contacts {}\n:tstamp \"{}\")",
out.to_string(), g_get_monotonic_time()));
@ -896,7 +900,8 @@ Server::Private::index_handler(const Command& cmd)
throw Error{Error::Code::Xapian, "indexer is already running"};
do_index(conf);
store().serialize();
if (const auto res{store().serialize()}; !res)
mu_warning("failed to serialize store: {}", res.error());
}
void

View File

@ -103,8 +103,10 @@ struct Store::Private {
if (conf)
config.import_configurable(*conf);
config.set<Config::Id::RootMaildir>(remove_slash(root_maildir));
config.set<Config::Id::SchemaVersion>(ExpectedSchemaVersion);
if (const auto res{config.set<Config::Id::RootMaildir>(remove_slash(root_maildir))}; !res)
throw res.error();
if (const auto res{config.set<Config::Id::SchemaVersion>(ExpectedSchemaVersion)}; !res)
throw res.error();
return config;
}
@ -420,8 +422,11 @@ Store::remove_message(const std::string& path)
for (auto&& label : doc.string_vec_value(Field::Id::Labels))
priv_->labels_cache_.decrease(label);
xapian_db().delete_document(term);
mu_debug("deleted message @ {} from store", path);
if (const auto res{xapian_db().delete_document(term)}; res)
mu_debug("deleted message @ {} from store", path);
else
mu_warning("failed to delete message @ {}: {}",
path, res.error());
return true;
}
@ -432,7 +437,8 @@ Store::remove_messages(const std::vector<Store::Id>& ids)
{
std::lock_guard guard{priv_->lock_};
xapian_db().request_transaction();
if (const auto res{xapian_db().request_transaction()}; !res)
mu_warning("failed to request transaction: {}", res.error());
for (auto&& id : ids)
priv_->remove_message_by_id_unlocked(id);
@ -464,7 +470,10 @@ Store::remove_messages_by_term(std::span<const std::string> terms,
std::vector<Xapian::Query> qvec;
std::vector<Store::Id> ids_to_remove;
xapian_db().request_transaction();
if (const auto res{xapian_db().request_transaction()}; !res) {
mu_error("failed to request transaction: {}", res.error());
return 0;
}
while (!terms.empty()) {
auto chunk = terms.subspan(0, std::min<size_t>(terms.size(), 1024));
@ -810,7 +819,11 @@ Store::maildirs() const
};
Scanner scanner{root_maildir(), handler, Scanner::Mode::MaildirsOnly};
scanner.start();
if (const auto res{scanner.start()}; !res) {
mu_warning("failed to start scanner: {}", res.error());
return {};
}
std::ranges::sort(mdirs);
return mdirs;

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2019-2025 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2019-2026 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
@ -107,7 +107,7 @@ struct Error final : public std::exception {
*
* @return
*/
virtual const char* what() const noexcept override { return what_.c_str(); }
const char* what() const noexcept override { return what_.c_str(); }
/**
* Get the error-code for this error
@ -183,7 +183,10 @@ private:
std::string hint_;
};
inline auto
/**
* Make Error formattable with libfmt
*/
inline std::string
format_as(const Error& err) {
return mu_format("<{} ({}:{})>",
err.what(),

View File

@ -53,15 +53,15 @@ Mu::mu_cmd_init(const Options& opts)
Config conf{mdb};
if (opts.init.max_msg_size)
conf.set<Config::Id::MaxMessageSize>(*opts.init.max_msg_size);
conf.checked_set<Config::Id::MaxMessageSize>(*opts.init.max_msg_size);
if (opts.init.batch_size && *opts.init.batch_size != 0)
conf.set<Config::Id::BatchSize>(*opts.init.batch_size);
conf.checked_set<Config::Id::BatchSize>(*opts.init.batch_size);
if (!opts.init.personal_addresses.empty())
conf.set<Config::Id::PersonalAddresses>(opts.init.personal_addresses);
conf.checked_set<Config::Id::PersonalAddresses>(opts.init.personal_addresses);
if (!opts.init.ignored_addresses.empty())
conf.set<Config::Id::IgnoredAddresses>(opts.init.ignored_addresses);
conf.checked_set<Config::Id::IgnoredAddresses>(opts.init.ignored_addresses);
if (opts.init.support_ngrams)
conf.set<Config::Id::NgramsEnabled>(true);
conf.checked_set<Config::Id::NgramsEnabled>(true);
return Store::make_new(opts.runtime_path(RuntimePath::XapianDb),
opts.init.maildir, conf);
@ -77,7 +77,9 @@ Mu::mu_cmd_init(const Options& opts)
// mildly hacky
Options opts_copy{opts};
opts_copy.info.topic = "store";
mu_cmd_info(*store, opts_copy);
if (const auto res{mu_cmd_info(*store, opts_copy)}; !res)
mu_warning("failed to show store info: {}",
res.error());
mu_println("Database is empty. You can use 'mu index' to fill it.");
}

View File

@ -67,7 +67,9 @@ label_update(Mu::Store& store, const Options& opts)
mu_println("labels: apply {} to {}", labelstr, msg->path());
if (!opts.labels.dry_run) {
store.update_labels(*msg, deltas);
if (const auto res{store.update_labels(*msg, deltas)}; !res)
mu_warning("failed to update labels for {}: {}",
msg->path(), res.error());
}
++n;
}
@ -101,7 +103,9 @@ label_clear(Mu::Store& store, const Options& opts)
mu_println("labels: clear all from {}", msg->path());
if (!opts.labels.dry_run) {
store.clear_labels(*msg);
if (const auto res{store.clear_labels(*msg)}; !res)
mu_warning("failed to clear labels for {}: {}",
msg->path(), res.error());
}
++n;
}

View File

@ -104,11 +104,13 @@ subr_cc_store_cfind(SCM store_scm, SCM pattern_scm, SCM personal_scm, SCM after_
// 0 means "unlimited"
const size_t maxnum = from_scm_with_default(max_results_scm, 0U, func, 5);
to_store(store_scm, func, 1).contacts_cache().for_each(
const auto res = to_store(store_scm, func, 1).contacts_cache().for_each(
[&](const auto& contact)->bool {
contacts = scm_cons(to_scm(contact), contacts);
return true;
}, pattern, personal, after, maxnum);
if (!res)
throw ScmError{ScmError::Id::WrongArg, func, 2, pattern_scm, "pattern"};
return scm_reverse_x(contacts, SCM_EOL);
} catch (const ScmError& scm_err) {