Compare commits

...

3 Commits

Author SHA1 Message Date
Bart
303205c117 Add stdexcept include header 2026-04-07 13:24:27 -04:00
Bart
ca1a387c2d Rename namespace in comment 2026-04-07 11:53:58 -04:00
Bart
b275f47a25 refactor: Improve exception handling (#6540) 2026-04-07 11:47:43 -04:00
15 changed files with 97 additions and 115 deletions

View File

@@ -134,7 +134,7 @@ public:
{
lowest_layer().shutdown(plain_socket::shutdown_both);
}
catch (boost::system::system_error& e)
catch (boost::system::system_error const& e)
{
ec = e.code();
}

View File

@@ -246,7 +246,7 @@ flow(
EitherAmount stepIn(*strand[0]->cachedIn());
for (auto i = 0; i < s; ++i)
{
bool valid;
bool valid = false;
std::tie(valid, stepIn) = strand[i]->validFwd(checkSB, checkAfView, stepIn);
if (!valid)
{

View File

@@ -5,6 +5,8 @@
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/st.h>
#include <stdexcept>
namespace xrpl {
namespace detail {
@@ -374,14 +376,14 @@ ApplyStateTable::erase(ReadView const& base, std::shared_ptr<SLE> const& sle)
{
auto const iter = items_.find(sle->key());
if (iter == items_.end())
LogicError("ApplyStateTable::erase: missing key");
Throw<std::logic_error>("ApplyStateTable::erase: missing key");
auto& item = iter->second;
if (item.second != sle)
LogicError("ApplyStateTable::erase: unknown SLE");
Throw<std::logic_error>("ApplyStateTable::erase: unknown SLE");
switch (item.first)
{
case Action::erase:
LogicError("ApplyStateTable::erase: double erase");
Throw<std::logic_error>("ApplyStateTable::erase: double erase");
break;
case Action::insert:
items_.erase(iter);
@@ -405,7 +407,7 @@ ApplyStateTable::rawErase(ReadView const& base, std::shared_ptr<SLE> const& sle)
switch (item.first)
{
case Action::erase:
LogicError("ApplyStateTable::rawErase: double erase");
Throw<std::logic_error>("ApplyStateTable::rawErase: double erase");
break;
case Action::insert:
items_.erase(result.first);
@@ -436,11 +438,11 @@ ApplyStateTable::insert(ReadView const& base, std::shared_ptr<SLE> const& sle)
switch (item.first)
{
case Action::cache:
LogicError("ApplyStateTable::insert: already cached");
Throw<std::logic_error>("ApplyStateTable::insert: already cached");
case Action::insert:
LogicError("ApplyStateTable::insert: already inserted");
Throw<std::logic_error>("ApplyStateTable::insert: already inserted");
case Action::modify:
LogicError("ApplyStateTable::insert: already modified");
Throw<std::logic_error>("ApplyStateTable::insert: already modified");
case Action::erase:
break;
}
@@ -466,7 +468,7 @@ ApplyStateTable::replace(ReadView const& base, std::shared_ptr<SLE> const& sle)
switch (item.first)
{
case Action::erase:
LogicError("ApplyStateTable::replace: already erased");
Throw<std::logic_error>("ApplyStateTable::replace: already erased");
case Action::cache:
item.first = Action::modify;
break;
@@ -482,14 +484,14 @@ ApplyStateTable::update(ReadView const& base, std::shared_ptr<SLE> const& sle)
{
auto const iter = items_.find(sle->key());
if (iter == items_.end())
LogicError("ApplyStateTable::update: missing key");
Throw<std::logic_error>("ApplyStateTable::update: missing key");
auto& item = iter->second;
if (item.second != sle)
LogicError("ApplyStateTable::update: unknown SLE");
Throw<std::logic_error>("ApplyStateTable::update: unknown SLE");
switch (item.first)
{
case Action::erase:
LogicError("ApplyStateTable::update: erased");
Throw<std::logic_error>("ApplyStateTable::update: erased");
break;
case Action::cache:
item.first = Action::modify;

View File

@@ -4,6 +4,7 @@
#include <xrpl/protocol/Protocol.h>
#include <limits>
#include <stdexcept>
#include <type_traits>
namespace xrpl {
@@ -40,10 +41,8 @@ findPreviousPage(ApplyView& view, Keylet const& directory, SLE::ref start)
{
node = view.peek(keylet::page(directory, page));
if (!node)
{ // LCOV_EXCL_START
LogicError("Directory chain: root back-pointer broken.");
// LCOV_EXCL_STOP
}
Throw<std::logic_error>(
"Directory chain: root back-pointer broken."); // LCOV_EXCL_LINE
}
auto indexes = node->getFieldV256(sfIndexes);
@@ -62,21 +61,20 @@ insertKey(
if (preserveOrder)
{
if (std::find(indexes.begin(), indexes.end(), key) != indexes.end())
LogicError("dirInsert: double insertion"); // LCOV_EXCL_LINE
Throw<std::logic_error>("dirInsert: double insertion"); // LCOV_EXCL_LINE
indexes.push_back(key);
}
else
{
// We can't be sure if this page is already sorted because
// it may be a legacy page we haven't yet touched. Take
// the time to sort it.
// We can't be sure if this page is already sorted because it may be a
// legacy page we haven't yet touched. Take the time to sort it.
std::sort(indexes.begin(), indexes.end());
auto pos = std::lower_bound(indexes.begin(), indexes.end(), key);
if (pos != indexes.end() && key == *pos)
LogicError("dirInsert: double insertion"); // LCOV_EXCL_LINE
Throw<std::logic_error>("dirInsert: double insertion"); // LCOV_EXCL_LINE
indexes.insert(pos, key);
}
@@ -129,8 +127,7 @@ insertPage(
node->setFieldH256(sfRootIndex, directory.key);
node->setFieldV256(sfIndexes, indexes);
// Save some space by not specifying the value 0 since
// it's the default.
// Save some space by not specifying the value 0 since it's the default.
if (page != 1)
node->setFieldU64(sfIndexPrevious, page - 1);
XRPL_ASSERT_PARTS(!nextPage, "xrpl::directory::insertPage", "nextPage has default value");
@@ -199,28 +196,24 @@ ApplyView::emptyDirDelete(Keylet const& directory)
auto nextPage = node->getFieldU64(sfIndexNext);
if (nextPage == rootPage && prevPage != rootPage)
LogicError("Directory chain: fwd link broken"); // LCOV_EXCL_LINE
Throw<std::logic_error>("Directory chain: fwd link broken"); // LCOV_EXCL_LINE
if (prevPage == rootPage && nextPage != rootPage)
LogicError("Directory chain: rev link broken"); // LCOV_EXCL_LINE
Throw<std::logic_error>("Directory chain: rev link broken"); // LCOV_EXCL_LINE
// Older versions of the code would, in some cases, allow the last
// page to be empty. Remove such pages:
// Older versions of the code would, in some cases, allow the last page to
// be empty. Remove such pages:
if (nextPage == prevPage && nextPage != rootPage)
{
auto last = peek(keylet::page(directory, nextPage));
if (!last)
{ // LCOV_EXCL_START
LogicError("Directory chain: fwd link broken.");
// LCOV_EXCL_STOP
}
Throw<std::logic_error>("Directory chain: fwd link broken."); // LCOV_EXCL_LINE
if (!last->getFieldV256(sfIndexes).empty())
return false;
// Update the first page's linked list and
// mark it as updated.
// Update the first page's linked list and mark it as updated.
node->setFieldU64(sfIndexNext, rootPage);
node->setFieldU64(sfIndexPrevious, rootPage);
update(node);
@@ -228,8 +221,7 @@ ApplyView::emptyDirDelete(Keylet const& directory)
// And erase the empty last page:
erase(last);
// Make sure our local values reflect the
// updated information:
// Make sure our local values reflect the updated information:
nextPage = rootPage;
prevPage = rootPage;
}
@@ -269,46 +261,33 @@ ApplyView::dirRemove(Keylet const& directory, std::uint64_t page, uint256 const&
return true;
}
// The current page is now empty; check if it can be
// deleted, and, if so, whether the entire directory
// can now be removed.
// The current page is now empty; check if it can be deleted, and, if so,
// whether the entire directory can now be removed.
auto prevPage = node->getFieldU64(sfIndexPrevious);
auto nextPage = node->getFieldU64(sfIndexNext);
// The first page is the directory's root node and is
// treated specially: it can never be deleted even if
// it is empty, unless we plan on removing the entire
// directory.
// The first page is the directory's root node and is treated specially: it
// can never be deleted even if it is empty, unless we plan on removing the
// entire directory.
if (page == rootPage)
{
if (nextPage == page && prevPage != page)
{ // LCOV_EXCL_START
LogicError("Directory chain: fwd link broken");
// LCOV_EXCL_STOP
}
Throw<std::logic_error>("Directory chain: fwd link broken"); // LCOV_EXCL_LINE
if (prevPage == page && nextPage != page)
{ // LCOV_EXCL_START
LogicError("Directory chain: rev link broken");
// LCOV_EXCL_STOP
}
Throw<std::logic_error>("Directory chain: rev link broken"); // LCOV_EXCL_LINE
// Older versions of the code would, in some cases,
// allow the last page to be empty. Remove such
// pages if we stumble on them:
// Older versions of the code would, in some cases, allow the last page
// to be empty. Remove such pages if we stumble on them:
if (nextPage == prevPage && nextPage != page)
{
auto last = peek(keylet::page(directory, nextPage));
if (!last)
{ // LCOV_EXCL_START
LogicError("Directory chain: fwd link broken.");
// LCOV_EXCL_STOP
}
Throw<std::logic_error>("Directory chain: fwd link broken."); // LCOV_EXCL_LINE
if (last->getFieldV256(sfIndexes).empty())
{
// Update the first page's linked list and
// mark it as updated.
// Update the first page's linked list and mark it as updated.
node->setFieldU64(sfIndexNext, page);
node->setFieldU64(sfIndexPrevious, page);
update(node);
@@ -316,8 +295,7 @@ ApplyView::dirRemove(Keylet const& directory, std::uint64_t page, uint256 const&
// And erase the empty last page:
erase(last);
// Make sure our local values reflect the
// updated information:
// Make sure our local values reflect the updated information:
nextPage = page;
prevPage = page;
}
@@ -335,25 +313,24 @@ ApplyView::dirRemove(Keylet const& directory, std::uint64_t page, uint256 const&
// This can never happen for nodes other than the root:
if (nextPage == page)
LogicError("Directory chain: fwd link broken"); // LCOV_EXCL_LINE
Throw<std::logic_error>("Directory chain: fwd link broken"); // LCOV_EXCL_LINE
if (prevPage == page)
LogicError("Directory chain: rev link broken"); // LCOV_EXCL_LINE
Throw<std::logic_error>("Directory chain: rev link broken"); // LCOV_EXCL_LINE
// This node isn't the root, so it can either be in the
// middle of the list, or at the end. Unlink it first
// and then check if that leaves the list with only a
// root:
// This node isn't the root, so it can either be in the middle of the list,
// or at the end. Unlink it first and then check if that leaves the list
// with only a root:
auto prev = peek(keylet::page(directory, prevPage));
if (!prev)
LogicError("Directory chain: fwd link broken."); // LCOV_EXCL_LINE
Throw<std::logic_error>("Directory chain: fwd link broken."); // LCOV_EXCL_LINE
// Fix previous to point to its new next.
prev->setFieldU64(sfIndexNext, nextPage);
update(prev);
auto next = peek(keylet::page(directory, nextPage));
if (!next)
LogicError("Directory chain: rev link broken."); // LCOV_EXCL_LINE
Throw<std::logic_error>("Directory chain: rev link broken."); // LCOV_EXCL_LINE
// Fix next to point to its new previous.
next->setFieldU64(sfIndexPrevious, prevPage);
update(next);
@@ -361,13 +338,12 @@ ApplyView::dirRemove(Keylet const& directory, std::uint64_t page, uint256 const&
// The page is no longer linked. Delete it.
erase(node);
// Check whether the next page is the last page and, if
// so, whether it's empty. If it is, delete it.
// Check whether the next page is the last page and, if so, whether it's
// empty. If it is, delete it.
if (nextPage != rootPage && next->getFieldU64(sfIndexNext) == rootPage &&
next->getFieldV256(sfIndexes).empty())
{
// Since next doesn't point to the root, it
// can't be pointing to prev.
// Since next doesn't point to the root, it can't be pointing to prev.
erase(next);
// The previous page is now the last page:
@@ -377,18 +353,16 @@ ApplyView::dirRemove(Keylet const& directory, std::uint64_t page, uint256 const&
// And the root points to the last page:
auto root = peek(keylet::page(directory, rootPage));
if (!root)
{ // LCOV_EXCL_START
LogicError("Directory chain: root link broken.");
// LCOV_EXCL_STOP
}
Throw<std::logic_error>("Directory chain: root link broken."); // LCOV_EXCL_LINE
root->setFieldU64(sfIndexPrevious, prevPage);
update(root);
nextPage = rootPage;
}
// If we're not keeping the root, then check to see if
// it's left empty. If so, delete it as well.
// If we're not keeping the root, then check to see if it's left empty.
// If so, delete it as well.
if (!keepRoot && nextPage == rootPage && prevPage == rootPage)
{
if (prev->getFieldV256(sfIndexes).empty())

View File

@@ -12,6 +12,7 @@
#include <xrpl/protocol/digest.h>
#include <xrpl/protocol/jss.h>
#include <stdexcept>
#include <utility>
#include <vector>
@@ -461,14 +462,14 @@ void
Ledger::rawErase(std::shared_ptr<SLE> const& sle)
{
if (!stateMap_.delItem(sle->key()))
LogicError("Ledger::rawErase: key not found");
Throw<std::logic_error>("Ledger::rawErase: key not found");
}
void
Ledger::rawErase(uint256 const& key)
{
if (!stateMap_.delItem(key))
LogicError("Ledger::rawErase: key not found");
Throw<std::logic_error>("Ledger::rawErase: key not found");
}
void
@@ -478,7 +479,7 @@ Ledger::rawInsert(std::shared_ptr<SLE> const& sle)
sle->add(ss);
if (!stateMap_.addGiveItem(
SHAMapNodeType::tnACCOUNT_STATE, make_shamapitem(sle->key(), ss.slice())))
LogicError("Ledger::rawInsert: key already exists");
Throw<std::logic_error>("Ledger::rawInsert: key already exists");
}
void
@@ -488,7 +489,7 @@ Ledger::rawReplace(std::shared_ptr<SLE> const& sle)
sle->add(ss);
if (!stateMap_.updateGiveItem(
SHAMapNodeType::tnACCOUNT_STATE, make_shamapitem(sle->key(), ss.slice())))
LogicError("Ledger::rawReplace: key not found");
Throw<std::logic_error>("Ledger::rawReplace: key not found");
}
void
@@ -504,7 +505,7 @@ Ledger::rawTxInsert(
s.addVL(txn->peekData());
s.addVL(metaData->peekData());
if (!txMap_.addGiveItem(SHAMapNodeType::tnTRANSACTION_MD, make_shamapitem(key, s.slice())))
LogicError("duplicate_tx: " + to_string(key));
Throw<std::logic_error>("duplicate_tx: " + to_string(key));
}
uint256
@@ -522,7 +523,7 @@ Ledger::rawTxInsertWithHash(
auto item = make_shamapitem(key, s.slice());
auto hash = sha512Half(HashPrefix::txNode, item->slice(), item->key());
if (!txMap_.addGiveItem(SHAMapNodeType::tnTRANSACTION_MD, std::move(item)))
LogicError("duplicate_tx: " + to_string(key));
Throw<std::logic_error>("duplicate_tx: " + to_string(key));
return hash;
}

View File

@@ -1,6 +1,8 @@
#include <xrpl/basics/contract.h>
#include <xrpl/ledger/OpenView.h>
#include <stdexcept>
namespace xrpl {
class OpenView::txs_iter_impl : public txs_type::iter_base
@@ -247,7 +249,7 @@ OpenView::rawTxInsert(
auto const result = txs_.emplace(
std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(txn, metaData));
if (!result.second)
LogicError("rawTxInsert: duplicate TX id: " + to_string(key));
Throw<std::logic_error>("rawTxInsert: duplicate TX id: " + to_string(key));
}
} // namespace xrpl

View File

@@ -1,6 +1,8 @@
#include <xrpl/basics/contract.h>
#include <xrpl/ledger/detail/RawStateTable.h>
#include <stdexcept>
namespace xrpl {
namespace detail {
@@ -241,7 +243,7 @@ RawStateTable::erase(std::shared_ptr<SLE> const& sle)
switch (item.action)
{
case Action::erase:
LogicError("RawStateTable::erase: already erased");
Throw<std::logic_error>("RawStateTable::erase: already erased");
break;
case Action::insert:
items_.erase(result.first);
@@ -270,10 +272,10 @@ RawStateTable::insert(std::shared_ptr<SLE> const& sle)
item.sle = sle;
break;
case Action::insert:
LogicError("RawStateTable::insert: already inserted");
Throw<std::logic_error>("RawStateTable::insert: already inserted");
break;
case Action::replace:
LogicError("RawStateTable::insert: already exists");
Throw<std::logic_error>("RawStateTable::insert: already exists");
break;
}
}
@@ -291,7 +293,7 @@ RawStateTable::replace(std::shared_ptr<SLE> const& sle)
switch (item.action)
{
case Action::erase:
LogicError("RawStateTable::replace: was erased");
Throw<std::logic_error>("RawStateTable::replace: was erased");
break;
case Action::insert:
case Action::replace:

View File

@@ -8,6 +8,7 @@
#include <algorithm>
#include <limits>
#include <stdexcept>
namespace xrpl {
@@ -153,7 +154,7 @@ getPseudoAccountFields()
if (!ar)
{
// LCOV_EXCL_START
LogicError(
Throw<std::logic_error>(
"xrpl::getPseudoAccountFields : unable to find account root "
"ledger format");
// LCOV_EXCL_STOP

View File

@@ -507,7 +507,7 @@ port_wss_admin
{
c.loadFromString(boost::str(configTemplate % validationSeed % token));
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -528,7 +528,7 @@ port_wss_admin
main
)xrpldConfig");
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -541,7 +541,7 @@ main
c.loadFromString(R"xrpldConfig(
)xrpldConfig");
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -556,7 +556,7 @@ main
255
)xrpldConfig");
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -571,7 +571,7 @@ main
10000
)xrpldConfig");
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -598,7 +598,7 @@ main
Config c;
c.loadFromString(boost::str(cc % missingPath));
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -617,7 +617,7 @@ main
Config c;
c.loadFromString(boost::str(cc % invalidFile.string()));
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -725,7 +725,7 @@ trust-these-validators.gov
c.loadFromString(toLoad);
fail();
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -754,7 +754,7 @@ value = 2
c.loadFromString(toLoad);
fail();
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -802,7 +802,7 @@ trust-these-validators.gov
c.loadFromString(toLoad);
fail();
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -948,7 +948,7 @@ trust-these-validators.gov
c.loadFromString(boost::str(cc % vtg.validatorsFile()));
fail();
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -974,7 +974,7 @@ trust-these-validators.gov
Config c2;
c2.loadFromString(boost::str(cc % vtg.validatorsFile()));
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -1451,7 +1451,7 @@ r.ripple.com:51235
fail();
}
}
catch (std::runtime_error&)
catch (std::runtime_error const&)
{
if (!shouldPass)
{
@@ -1477,7 +1477,7 @@ r.ripple.com:51235
c.loadFromString("[overlay]\nmax_unknown_time=" + value);
return c.MAX_UNKNOWN_TIME;
}
catch (std::runtime_error&)
catch (std::runtime_error const&)
{
return {};
}
@@ -1511,7 +1511,7 @@ r.ripple.com:51235
c.loadFromString("[overlay]\nmax_diverged_time=" + value);
return c.MAX_DIVERGED_TIME;
}
catch (std::runtime_error&)
catch (std::runtime_error const&)
{
return {};
}

View File

@@ -1345,7 +1345,7 @@ vp_enable=0
{
c.loadFromString(toLoad);
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}
@@ -1389,7 +1389,7 @@ vp_base_squelch_max_selected_peers=2
{
c2.loadFromString(toLoad);
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
error = e.what();
}

View File

@@ -2130,7 +2130,7 @@ class STParsedJSON_test : public beast::unit_test::suite
STParsedJSONObject const parsed("test", faultyJson);
BEAST_EXPECT(!parsed.object);
}
catch (std::runtime_error& e)
catch (std::runtime_error const& e)
{
std::string const what(e.what());
unexpected(what.find("First level children of `Template`") != 0);

View File

@@ -1632,7 +1632,7 @@ rpcClient(
// YYY We could have a command line flag for single line output for
// scripts. YYY We would intercept output here and simplify it.
}
catch (RequestNotParsable& e)
catch (RequestNotParsable const& e)
{
jvOutput = rpcError(rpcINVALID_PARAMS);
jvOutput["error_what"] = e.what();

View File

@@ -614,7 +614,7 @@ transactionPreProcessImpl(
stTx = std::make_shared<STTx>(std::move(parsed.object.value()));
}
catch (STObject::FieldErr& err)
catch (STObject::FieldErr const& err)
{
return RPC::make_error(rpcINVALID_PARAMS, err.what());
}
@@ -1286,7 +1286,7 @@ transactionSubmitMultiSigned(
{
stTx = std::make_shared<STTx>(std::move(parsedTx_json.object.value()));
}
catch (STObject::FieldErr& err)
catch (STObject::FieldErr const& err)
{
return RPC::make_error(rpcINVALID_PARAMS, err.what());
}

View File

@@ -897,7 +897,7 @@ doLedgerEntry(RPC::JsonContext& context)
return RPC::make_param_error("No ledger_entry params provided.");
}
}
catch (Json::error& e)
catch (Json::error const& e)
{
if (context.apiVersion > 1u)
{

View File

@@ -65,7 +65,7 @@ doSubscribe(RPC::JsonContext& context)
ispSub =
context.netOps.addRpcSub(strUrl, std::dynamic_pointer_cast<InfoSub>(rspSub));
}
catch (std::runtime_error& ex)
catch (std::runtime_error const& ex)
{
return RPC::make_param_error(ex.what());
}