Use BacktraceException for appropriate (most) exceptions

This commit is contained in:
Ken Sedgwick 2024-07-25 17:00:18 -07:00
parent 0509c1326e
commit 39a09c2908
40 changed files with 99 additions and 76 deletions

View file

@ -88,9 +88,9 @@ Tx::Tx(std::string const& s) {
auto is = std::istringstream(std::move(str));
is >> *this;
if (!is.good())
throw std::invalid_argument("Bitcoin::Tx: invalid hex string input.");
throw Util::BacktraceException<std::invalid_argument>("Bitcoin::Tx: invalid hex string input.");
if (is.get() != std::char_traits<char>::eof())
throw std::invalid_argument("Bitcoin::Tx: input string too long.");
throw Util::BacktraceException<std::invalid_argument>("Bitcoin::Tx: input string too long.");
}
Bitcoin::TxId Tx::get_txid() const {

View file

@ -1,6 +1,7 @@
#ifndef BITCOIN_ADDR_TO_SCRIPTPUBKEY_HPP
#define BITCOIN_ADDR_TO_SCRIPTPUBKEY_HPP
#include"Util/BacktraceException.hpp"
#include<cstdint>
#include<string>
#include<stdexcept>
@ -8,10 +9,10 @@
namespace Bitcoin {
struct UnknownAddrType : public std::invalid_argument {
struct UnknownAddrType : public Util::BacktraceException<std::invalid_argument> {
public:
UnknownAddrType()
: std::invalid_argument("Bitcoin::UnknownAddrType") { }
: Util::BacktraceException<std::invalid_argument>("Bitcoin::UnknownAddrType") { }
};
/** Bitcoin::addr_to_scriptPubKey

View file

@ -19,10 +19,10 @@ enum SighashFlags
, SIGHASH_ANYONECANPAY = 0x80
};
struct InvalidSighash : public std::invalid_argument {
struct InvalidSighash : public Util::BacktraceException<std::invalid_argument> {
InvalidSighash() =delete;
InvalidSighash(std::string const& msg)
: std::invalid_argument(
: Util::BacktraceException<std::invalid_argument>(
std::string("Bitcoin::InvalidSighash: ") + msg
) { }
};

View file

@ -1,6 +1,7 @@
#ifndef BOLTZ_CONNECTIONIF_HPP
#define BOLTZ_CONNECTIONIF_HPP
#include"Util/BacktraceException.hpp"
#include<memory>
#include<stdexcept>
#include<string>
@ -35,10 +36,10 @@ public:
* @brief thrown when communications with
* the BOLTZ server has problems.
*/
class ApiError : public std::runtime_error {
class ApiError : public Util::BacktraceException<std::runtime_error> {
public:
ApiError(std::string const& e
) : std::runtime_error(e) { }
) : Util::BacktraceException<std::runtime_error>(e) { }
};
}

View file

@ -104,7 +104,7 @@ private:
, meth
, is.c_str()
).then([]() {
throw std::runtime_error("Unexpected result.");
throw Util::BacktraceException<std::runtime_error>("Unexpected result.");
return Ev::lift();
});
}

View file

@ -60,7 +60,7 @@ std::string RpcError::make_error_message( std::string const& command
RpcError::RpcError( std::string command_
, Jsmn::Object error_
) : std::runtime_error(make_error_message(command_, error_))
) : Util::BacktraceException<std::runtime_error>(make_error_message(command_, error_))
, command(command_)
, error(error_)
{ }
@ -200,13 +200,13 @@ private:
return std::size_t(0);
}
if (res < 0)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Rpc: read: ") +
strerror(errno)
);
if (res == 0)
/* Unexpected end of file! */
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
"Rpc: read: unexpected end-of-file "
"in RPC socket."
);
@ -263,7 +263,7 @@ private:
))
break;
if (res < 0)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Rpc: write: ") +
strerror(errno)
);

View file

@ -13,7 +13,7 @@ namespace S { class Bus; }
namespace Boss { namespace Mod {
struct RpcError : public std::runtime_error {
struct RpcError : public Util::BacktraceException<std::runtime_error> {
private:
static
std::string make_error_message( std::string const&

View file

@ -272,7 +272,7 @@ private:
for (auto const& tag : tags) {
auto it = tag_informs.find(tag);
if (it == tag_informs.end())
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Unknown tag: ") + tag
);
}

View file

@ -77,7 +77,7 @@ void try_create_privkey_file( std::string const& privkey_filename
/* Benign failure, file already exists. */
return;
if (!fd)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Boss::Signer: creat(\"") +
privkey_filename +
"\"): " + strerror(errno)
@ -88,7 +88,7 @@ void try_create_privkey_file( std::string const& privkey_filename
auto res = Util::Rw::write_all(fd.get(), &sk, sizeof(sk));
if (!res) {
unlink_noerr(privkey_filename);
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Boss::Signer: write(\"") +
privkey_filename +
"\"): " + strerror(errno)
@ -101,7 +101,7 @@ Secp256k1::PrivKey
read_privkey_file(std::string const& privkey_filename) {
auto fd = Net::Fd(open(privkey_filename.c_str(), O_RDONLY));
if (!fd)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Boss::Signer: open(\"") +
privkey_filename +
"\"): " + strerror(errno)
@ -111,13 +111,13 @@ read_privkey_file(std::string const& privkey_filename) {
auto size = sizeof(sk);
auto res = Util::Rw::read_all(fd.get(), &sk, size);
if (!res)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Boss::Signer: read(\"") +
privkey_filename +
"\"): " + strerror(errno)
);
if (size != sizeof(sk))
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Boss::Signer: read(\"") +
privkey_filename +
"\"): unexpected end-of-file"
@ -196,7 +196,7 @@ public:
/* Check it matches. */
auto actual_pk = Secp256k1::PubKey(self->sk);
if (actual_pk != pubkey)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Boss::Signer: ") +
self->privkey_filename +
": not matched to database!"

View file

@ -1,5 +1,6 @@
#include"Boss/open_rpc_socket.hpp"
#include"Net/Fd.hpp"
#include"Util/BacktraceException.hpp"
#include<errno.h>
#include<stdexcept>
#include<string.h>
@ -15,19 +16,19 @@ Net::Fd open_rpc_socket( std::string const& lightning_dir
) {
auto chdir_res = chdir(lightning_dir.c_str());
if (chdir_res < 0)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("chdir: ") + strerror(errno)
);
auto fd = Net::Fd(socket(AF_UNIX, SOCK_STREAM, 0));
if (!fd)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("socket: ") + strerror(errno)
);
auto addr = sockaddr_un();
if (rpc_file.length() + 1 > sizeof(addr.sun_path))
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("sizeof(sun_path): ") + strerror(ENOSPC)
);
@ -42,7 +43,7 @@ Net::Fd open_rpc_socket( std::string const& lightning_dir
);
} while (connect_res < 0 && errno == EINTR);
if (connect_res < 0)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("connect: ") + strerror(errno)
);

View file

@ -1,5 +1,6 @@
#include"Boss/random_engine.hpp"
#include"Net/Fd.hpp"
#include"Util/BacktraceException.hpp"
#include<errno.h>
#include<fcntl.h>
#include<stdexcept>
@ -18,7 +19,7 @@ std::default_random_engine initialize_random_engine() {
dr = Net::Fd(open("/dev/random", O_RDONLY));
} while (!dr && errno == EINTR);
if (!dr)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("open /dev/random: ") +
strerror(errno)
);

View file

@ -1,4 +1,5 @@
#include"DnsSeed/Detail/decode_bech32_node.hpp"
#include"Util/BacktraceException.hpp"
#include"Util/Bech32.hpp"
#include<algorithm>
#include<ctype.h>
@ -12,19 +13,19 @@ std::vector<std::uint8_t> decode_bech32_node(std::string const& s) {
auto bitstream = std::vector<bool>();
if (!Util::Bech32::decode(hrp, bitstream, s))
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Not a bech32 string: ") + s
);
/* 264 bits needed, but bech32 encodes in batches of 5 bits so
* we round up to 265. */
if (bitstream.size() != 33 * 8 + 1)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Data part wrong size: ") + s
);
/* The last bit should be 0. */
if (bitstream[264] == 1)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Odd node id: ") + s
);
/* And should be removed. */

View file

@ -12,6 +12,7 @@
#include<unistd.h>
#include<vector>
#include"Ev/ThreadPool.hpp"
#include"Util/BacktraceException.hpp"
#include"Util/make_unique.hpp"
namespace {
@ -182,7 +183,7 @@ public:
int pipes[2];
auto pipe_res = pipe(pipes);
if (pipe_res < 0) {
throw std::runtime_error(std::string("Ev::ThreadPool: pipe:")
throw Util::BacktraceException<std::runtime_error>(std::string("Ev::ThreadPool: pipe:")
+ strerror(errno)
);
}

View file

@ -1,6 +1,7 @@
#include"Ev/Io.hpp"
#include"Ev/runcmd.hpp"
#include"Net/Fd.hpp"
#include"Util/BacktraceException.hpp"
#include"Util/make_unique.hpp"
#include<errno.h>
#include<ev.h>
@ -62,7 +63,7 @@ private:
static
void error(std::unique_ptr<RunCmd> self, std::string msg) {
try {
throw std::runtime_error(
throw Util::BacktraceException<Util::BacktraceException<std::runtime_error>>(
std::string("pipecmd: ") + msg +
": " + strerror(errno)
);

View file

@ -386,7 +386,7 @@ std::istream& operator>>(std::istream& is, Jsmn::Object& o) {
if (!is || is.eof() || !is.get(buf[0])) {
if (!started)
return is;
throw std::runtime_error("Unexpected end-of-file.");
throw Util::BacktraceException<std::runtime_error>("Unexpected end-of-file.");
}
started = true;

View file

@ -7,6 +7,7 @@
#include<memory>
#include<ostream>
#include<stdexcept>
#include"Util/BacktraceException.hpp"
#include<string>
#include<vector>
@ -16,10 +17,9 @@ namespace Jsmn { class ParserExposedBuffer; }
namespace Jsmn {
/* Thrown when converting or using as incorrect type. */
/* FIXME: Use a backtrace-catching exception. */
class TypeError : public std::invalid_argument {
class TypeError : public Util::BacktraceException<std::invalid_argument> {
public:
TypeError() : std::invalid_argument("Incorrect type.") { }
TypeError() : Util::BacktraceException<std::invalid_argument>("Incorrect type.") { }
};
/* Represents an object that has been parsed from a JSON string. */

View file

@ -1,6 +1,7 @@
#ifndef JSMN_PARSEERROR_HPP
#define JSMN_PARSEERROR_HPP
#include"Util/BacktraceException.hpp"
#include<stdexcept>
#include<string>
#include<utility>
@ -8,7 +9,7 @@
namespace Jsmn {
/* Thrown on JSON parsing failure. */
class ParseError : public std::runtime_error {
class ParseError : public Util::BacktraceException<std::runtime_error> {
private:
std::string input;
unsigned int i;
@ -20,7 +21,7 @@ public:
ParseError() =delete;
ParseError( std::string input_
, unsigned int i_
) : std::runtime_error(enmessage(input_, i_))
) : Util::BacktraceException<std::runtime_error>(enmessage(input_, i_))
, input(std::move(input_))
, i(i_)
{

View file

@ -1,4 +1,5 @@
#include"Ln/Amount.hpp"
#include"Util/BacktraceException.hpp"
#include<algorithm>
#include<sstream>
#include<stdexcept>
@ -44,12 +45,12 @@ Amount::object(Jsmn::Object const& o) {
else if (o.is_string())
return Amount(std::string(o));
else
throw std::invalid_argument("Ln::Amount json object invalid.");
throw Util::BacktraceException<std::invalid_argument>("Ln::Amount json object invalid.");
}
Amount::Amount(std::string const& s) {
if (!valid_string(s))
throw std::invalid_argument("Ln::Amount string invalid.");
throw Util::BacktraceException<std::invalid_argument>("Ln::Amount string invalid.");
auto is = std::istringstream(std::string(s.begin(), s.end() - 4));
is >> v;
}

View file

@ -19,7 +19,7 @@ namespace Ln {
NodeId::NodeId(std::string const& s) {
/* Parse. */
if (!valid_string(s))
throw std::range_error(
throw Util::BacktraceException<std::range_error>(
std::string("Ln::NodeId: not node ID: ") + s
);

View file

@ -29,7 +29,7 @@ bool Preimage::valid_string(std::string const& s) {
Preimage::Preimage(std::string const& s) : pimpl(std::make_shared<Impl>()) {
auto buf = Util::Str::hexread(s);
if (buf.size() != 32)
throw std::invalid_argument("Ln::Preimage: wrong size.");
throw Util::BacktraceException<std::invalid_argument>("Ln::Preimage: wrong size.");
for (auto i = 0; i < 32; ++i)
pimpl->data[i] = buf[i];
}

View file

@ -1,4 +1,5 @@
#include"Ln/Scid.hpp"
#include"Util/BacktraceException.hpp"
#include<algorithm>
#include<sstream>
#include<stdexcept>
@ -82,7 +83,7 @@ Scid::Scid(std::string const& s) {
auto t = std::uint64_t();
auto o = std::uint64_t();
if (!validate_and_parse(s, b, t, o))
throw std::invalid_argument(std::string("Not an SCID: ") + s);
throw Util::BacktraceException<std::invalid_argument>(std::string("Not an SCID: ") + s);
val = (b << 40)
| (t << 16)
| (o << 0)

View file

@ -1,6 +1,7 @@
#ifndef NET_IPADDR_HPP
#define NET_IPADDR_HPP
#include"Util/BacktraceException.hpp"
#include<cstdint>
#include<memory>
#include<ostream>
@ -17,11 +18,11 @@ namespace Net {
*
* @brief thrown when an invalid IP address is given.
*/
class IPAddrInvalid : public std::invalid_argument {
class IPAddrInvalid : public Util::BacktraceException<std::invalid_argument> {
public:
std::string invalid_ip;
explicit IPAddrInvalid( std::string const& invalid_ip_
) : std::invalid_argument( std::string("Invalid IP: ")
) : Util::BacktraceException<std::invalid_argument>( std::string("Invalid IP: ")
+ invalid_ip_
)
, invalid_ip(invalid_ip_)

View file

@ -5,6 +5,7 @@
#include<sys/socket.h>
#include<unistd.h>
#include"Net/SocketFd.hpp"
#include"Util/BacktraceException.hpp"
namespace Net {
@ -59,7 +60,7 @@ void SocketFd::write(std::vector<std::uint8_t> const& data) {
);
} while (res < 0 && errno == EINTR);
if (res < 0)
throw std::runtime_error( std::string("Net::SocketFd::write: write: ")
throw Util::BacktraceException<std::runtime_error>( std::string("Net::SocketFd::write: write: ")
+ strerror(errno)
);
ptr += res;
@ -78,7 +79,7 @@ std::vector<std::uint8_t> SocketFd::read(std::size_t size) {
);
} while (res < 0 && errno == EINTR);
if (res < 0)
throw std::runtime_error( std::string("Net::SocketFd::read: read: ")
throw Util::BacktraceException<std::runtime_error>( std::string("Net::SocketFd::read: read: ")
+ strerror(errno)
);
if (res == 0) {

View file

@ -19,7 +19,7 @@ bool Hash::valid_string(std::string const& s) {
Hash::Hash(std::string const& s) : pimpl(std::make_shared<Impl>()) {
auto buf = Util::Str::hexread(s);
if (buf.size() != 20)
throw std::invalid_argument(
throw Util::BacktraceException<std::invalid_argument>(
"Ripemd160::Hash: incorrect size."
);
from_buffer(&buf[0]);

View file

@ -2,12 +2,13 @@
#include<stdexcept>
#include<string>
#include"Secp256k1/Detail/context.hpp"
#include"Util/BacktraceException.hpp"
namespace {
/* Called due to illegal inputs to the library. */
void illegal_callback(const char* msg, void*) {
throw std::invalid_argument(std::string("SECP256K1: ") + msg);
throw Util::BacktraceException<std::invalid_argument>(std::string("SECP256K1: ") + msg);
}
std::shared_ptr<secp256k1_context_struct> create_secp256k1_context() {

View file

@ -68,7 +68,7 @@ PrivKey& PrivKey::operator+=(PrivKey const& o) {
auto res = secp256k1_ec_seckey_tweak_add(context.get(), key, o.key);
/* FIXME: Use a backtrace-catching exception. */
if (!res)
throw std::out_of_range("Secp256k1::PrivKey += out-of-range");
throw Util::BacktraceException<std::out_of_range>("Secp256k1::PrivKey += out-of-range");
return *this;
}
@ -76,7 +76,7 @@ PrivKey& PrivKey::operator*=(PrivKey const& o) {
auto res = secp256k1_ec_seckey_tweak_mul(context.get(), key, o.key);
/* FIXME: Use a backtrace-catching exception. */
if (!res)
throw std::out_of_range("Secp256k1::PrivKey += out-of-range");
throw Util::BacktraceException<std::out_of_range>("Secp256k1::PrivKey += out-of-range");
return *this;
}

View file

@ -1,6 +1,7 @@
#ifndef SECP256K1_PRIVKEY_HPP
#define SECP256K1_PRIVKEY_HPP
#include"Util/BacktraceException.hpp"
#include<cstdint>
#include<ostream>
#include<stdexcept>
@ -19,9 +20,9 @@ namespace Secp256k1 {
* private key.
*/
/* FIXME: derive from a backtrace-capturing exception. */
class InvalidPrivKey : public std::invalid_argument {
class InvalidPrivKey : public Util::BacktraceException<std::invalid_argument> {
public:
InvalidPrivKey() : std::invalid_argument("Invalid private key.") {}
InvalidPrivKey() : Util::BacktraceException<std::invalid_argument>("Invalid private key.") {}
};
class PrivKey {

View file

@ -67,7 +67,7 @@ public:
);
/* FIXME: use a backtrace-prserving exception. */
if (!res)
throw std::out_of_range(
throw Util::BacktraceException<std::out_of_range>(
"Secp256k1::PubKey::operatoor+=: "
"result of adding PubKey out-of-range"
);
@ -83,7 +83,7 @@ public:
, sk.key
);
if (!res)
throw std::out_of_range(
throw Util::BacktraceException<std::out_of_range>(
"Secp256k1::PubKey::operatoor*=: "
"result of multiplying PrivKey out-of-range"
);

View file

@ -1,6 +1,7 @@
#ifndef SECP256K1_PUBKEY_HPP
#define SECP256K1_PUBKEY_HPP
#include"Util/BacktraceException.hpp"
#include<cstdint>
#include<functional>
#include<istream>
@ -23,9 +24,9 @@ std::ostream& operator<<(std::ostream&, Secp256k1::PubKey const&);
namespace Secp256k1 {
/* Thrown in case of being fed an invalid public key. */
class InvalidPubKey : public std::invalid_argument {
class InvalidPubKey : public Util::BacktraceException<std::invalid_argument> {
public:
InvalidPubKey() : std::invalid_argument("Invalid public key.") { }
InvalidPubKey() : Util::BacktraceException<std::invalid_argument>("Invalid public key.") { }
};
class PubKey {

View file

@ -46,7 +46,7 @@ Signature::Signature( Secp256k1::PrivKey const& sk
/* Extremely unlikely to happen.
* TODO: backtrace-capturing.
*/
throw std::runtime_error("Nonce generation for signing failed.");
throw Util::BacktraceException<std::runtime_error>("Nonce generation for signing failed.");
++(*reinterpret_cast<std::uint64_t*>(extra_entropy));
} while (!sig_has_low_r());
}

View file

@ -1,6 +1,7 @@
#ifndef SECP256K1_SIGNATURE_HPP
#define SECP256K1_SIGNATURE_HPP
#include"Util/BacktraceException.hpp"
#include<cstdint>
#include<stdexcept>
#include<string>
@ -12,10 +13,11 @@ namespace Sha256 { class Hash; }
namespace Secp256k1 {
class BadSignatureEncoding : public std::invalid_argument {
class BadSignatureEncoding : public Util::BacktraceException<std::invalid_argument> {
public:
BadSignatureEncoding()
: std::invalid_argument("Bad signature encoding")
: Util::BacktraceException<std::invalid_argument>("Bad signature encoding")
{ }
};

View file

@ -17,7 +17,7 @@ bool Hash::valid_string(std::string const& s) {
Hash::Hash(std::string const& s) {
auto bytes = Util::Str::hexread(s);
if (bytes.size() != 32)
throw std::invalid_argument("Hashes must be 32 bytes.");
throw Util::BacktraceException<std::invalid_argument>("Hashes must be 32 bytes.");
pimpl = std::make_shared<Impl>();
for (auto i = std::size_t(0); i < 32; ++i)
pimpl->d[i] = bytes[i];

View file

@ -1,5 +1,6 @@
#include"Ev/Io.hpp"
#include"Ev/yield.hpp"
#include"Util/BacktraceException.hpp"
#include"Sqlite3/Db.hpp"
#include"Sqlite3/Tx.hpp"
#include<stdexcept>
@ -28,7 +29,7 @@ public:
connection = nullptr;
} else
msg = "Not enough memory";
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Sqlite3::Db: sqlite3_open: ") +
msg
);
@ -38,7 +39,7 @@ public:
auto msg = std::string(sqlite3_errmsg(connection));
sqlite3_close_v2(connection);
connection = nullptr;
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Sqlite3::Db: sqlite3_extended_result_codes: ") +
msg
);
@ -50,7 +51,7 @@ public:
auto msg = std::string(sqlite3_errmsg(connection));
sqlite3_close_v2(connection);
connection = nullptr;
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Sqlite3::Db: "
"PRAGMA foreign_keys = ON: "
) +

View file

@ -1,3 +1,4 @@
#include"Util/BacktraceException.hpp"
#include"Sqlite3/Detail/binds.hpp"
#include<sqlite3.h>
#include<stdexcept>
@ -9,14 +10,14 @@ void bind_d(void* stmt, int l, double v) {
, l, v
);
if (res != SQLITE_OK)
throw std::runtime_error("Sqlite3: bind error.");
throw Util::BacktraceException<std::runtime_error>("Sqlite3: bind error.");
}
void bind_i(void* stmt, int l, std::int64_t v) {
auto res = sqlite3_bind_int64( (sqlite3_stmt*) stmt
, l, v
);
if (res != SQLITE_OK)
throw std::runtime_error("Sqlite3: bind error.");
throw Util::BacktraceException<std::runtime_error>("Sqlite3: bind error.");
}
void bind_s(void* stmt, int l, std::string v) {
auto res = sqlite3_bind_text( (sqlite3_stmt*) stmt
@ -24,12 +25,12 @@ void bind_s(void* stmt, int l, std::string v) {
, SQLITE_TRANSIENT
);
if (res != SQLITE_OK)
throw std::runtime_error("Sqlite3: bind error.");
throw Util::BacktraceException<std::runtime_error>("Sqlite3: bind error.");
}
void bind_null(void* stmt, int l) {
auto res = sqlite3_bind_null( (sqlite3_stmt*) stmt, l);
if (res != SQLITE_OK)
throw std::runtime_error("Sqlite3: bind error.");
throw Util::BacktraceException<std::runtime_error>("Sqlite3: bind error.");
}
}}

View file

@ -1,6 +1,7 @@
#include"Sqlite3/Db.hpp"
#include"Sqlite3/Query.hpp"
#include"Sqlite3/Result.hpp"
#include"Util/BacktraceException.hpp"
#include"Util/make_unique.hpp"
#include<sqlite3.h>
#include<stdexcept>
@ -27,7 +28,7 @@ public:
int get_location(char const* field) const {
auto res = sqlite3_bind_parameter_index(stmt, field);
if (res == 0)
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Sqlite3::Query::bind: "
"no field: "
) + field

View file

@ -1,3 +1,4 @@
#include"Util/BacktraceException.hpp"
#include"Sqlite3/Db.hpp"
#include"Sqlite3/Result.hpp"
#include<sqlite3.h>
@ -30,7 +31,7 @@ bool Result::advance() {
else {
auto connection = (sqlite3*) db.get_connection();
auto err = std::string(sqlite3_errmsg(connection));
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Sqlite3::Result: ") + err
);
}

View file

@ -1,6 +1,7 @@
#include"Sqlite3/Db.hpp"
#include"Sqlite3/Query.hpp"
#include"Sqlite3/Tx.hpp"
#include"Util/BacktraceException.hpp"
#include"Util/make_unique.hpp"
#include<stdexcept>
#include<sqlite3.h>
@ -15,7 +16,7 @@ private:
void throw_sqlite3(char const* src) {
auto connection = (sqlite3*) db.get_connection();
auto err = std::string(sqlite3_errmsg(connection));
throw std::runtime_error(
throw Util::BacktraceException<std::runtime_error>(
std::string("Sqlite3::Tx: ") + src + ": " + err
);
}

View file

@ -1,6 +1,7 @@
#ifndef STATS_WEIGHTEDMEDIAN_HPP
#define STATS_WEIGHTEDMEDIAN_HPP
#include"Util/BacktraceException.hpp"
#include<algorithm>
#include<functional>
#include<stdexcept>
@ -14,9 +15,9 @@ namespace Stats {
* @brief thrown when the weighted-median is
* extracted but there are no samples.
*/
class NoSamples : public std::invalid_argument {
class NoSamples : public Util::BacktraceException<std::invalid_argument> {
public:
NoSamples() : std::invalid_argument("Stats::NoSamples") { }
NoSamples() : Util::BacktraceException<std::invalid_argument>("Stats::NoSamples") { }
};
/** class Stats::WeightedMedian

View file

@ -5,6 +5,7 @@
* Minor string utilities.
*/
#include"Util/BacktraceException.hpp"
#include<cstdint>
#include<stdarg.h>
#include<stdexcept>
@ -20,10 +21,9 @@ std::string hexbyte(std::uint8_t);
std::string hexdump(void const* p, std::size_t s);
/* Creates a buffer from the given hex string. */
/* FIXME: use a backtrace-extracting exception. */
struct HexParseFailure : public std::runtime_error {
struct HexParseFailure : public Util::BacktraceException<std::runtime_error> {
HexParseFailure(std::string msg)
: std::runtime_error("hexread: " + msg) { }
: Util::BacktraceException<std::runtime_error>("hexread: " + msg) { }
};
std::vector<std::uint8_t> hexread(std::string const&);

View file

@ -39,7 +39,7 @@ Uuid::Uuid(std::string const& s) {
pimpl = Util::make_unique<Impl>();
auto buf = Util::Str::hexread(s);
if (buf.size() != 16)
throw std::invalid_argument("Uuid: invalid input string.");
throw Util::BacktraceException<std::invalid_argument>("Uuid: invalid input string.");
std::copy(buf.begin(), buf.end(), pimpl->data);
}
bool Uuid::valid_string(std::string const& s) {