aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-12-11 09:42:06 -0500
committerJack Lloyd <[email protected]>2015-12-11 09:42:06 -0500
commit6b9a3a534071ef84c121c406559f8fc7ad546104 (patch)
treec11480ad1f07e443ba4e992fefcd618b532c2e93 /src/lib/utils
parent79a51627ee11f4d7f55d589751b30463d1f02a76 (diff)
Reroot the exception hierarchy into a toplevel Exception class
As the alternatives are unfortunate for applications trying to catch all library errors, and it seems deriving from std::runtime_error causes problems with MSVC DLLs (GH #340) Effectively reverts 2837e915d82e43
Diffstat (limited to 'src/lib/utils')
-rw-r--r--src/lib/utils/assert.cpp2
-rw-r--r--src/lib/utils/dyn_load/dyn_load.cpp4
-rw-r--r--src/lib/utils/exceptn.h33
-rw-r--r--src/lib/utils/http_util/http_util.cpp16
-rw-r--r--src/lib/utils/http_util/http_util.h2
-rw-r--r--src/lib/utils/parsing.cpp2
-rw-r--r--src/lib/utils/read_cfg.cpp2
-rw-r--r--src/lib/utils/sqlite3/sqlite3.cpp16
8 files changed, 44 insertions, 33 deletions
diff --git a/src/lib/utils/assert.cpp b/src/lib/utils/assert.cpp
index 978fc12a1..d729a8368 100644
--- a/src/lib/utils/assert.cpp
+++ b/src/lib/utils/assert.cpp
@@ -30,7 +30,7 @@ void assertion_failure(const char* expr_str,
format << "@" << file << ":" << line;
- throw std::runtime_error(format.str());
+ throw Exception(format.str());
}
}
diff --git a/src/lib/utils/dyn_load/dyn_load.cpp b/src/lib/utils/dyn_load/dyn_load.cpp
index 723d2502e..9b99331d1 100644
--- a/src/lib/utils/dyn_load/dyn_load.cpp
+++ b/src/lib/utils/dyn_load/dyn_load.cpp
@@ -22,7 +22,7 @@ namespace {
void raise_runtime_loader_exception(const std::string& lib_name,
const char* msg)
{
- throw std::runtime_error("Failed to load " + lib_name + ": " +
+ throw Exception("Failed to load " + lib_name + ": " +
(msg ? msg : "Unknown error"));
}
@@ -70,7 +70,7 @@ void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol)
#endif
if(!addr)
- throw std::runtime_error("Failed to resolve symbol " + symbol +
+ throw Exception("Failed to resolve symbol " + symbol +
" in " + lib_name);
return addr;
diff --git a/src/lib/utils/exceptn.h b/src/lib/utils/exceptn.h
index eef1b4d43..c9b45f916 100644
--- a/src/lib/utils/exceptn.h
+++ b/src/lib/utils/exceptn.h
@@ -16,8 +16,28 @@
namespace Botan {
-typedef std::runtime_error Exception;
-typedef std::invalid_argument Invalid_Argument;
+/**
+* Base class for all exceptions thrown by the library
+*/
+class BOTAN_DLL Exception : public std::exception
+ {
+ public:
+ Exception(const std::string& what) : m_what(what) {}
+ Exception(const char* prefix, const std::string& what) : m_what(std::string(prefix) + " " + what) {}
+ const char* what() const override { return m_what.c_str(); }
+ private:
+ std::string m_what;
+ };
+
+/**
+* An invalid argument which caused
+*/
+class BOTAN_DLL Invalid_Argument : public Exception
+ {
+ public:
+ Invalid_Argument(const std::string& what) :
+ Exception("Invalid argument", what) {}
+ };
/**
* Unsupported_Argument Exception
@@ -196,15 +216,6 @@ struct BOTAN_DLL Self_Test_Failure : public Internal_Error
{}
};
-/**
-* Memory Allocation Exception
-*/
-struct BOTAN_DLL Memory_Exhaustion : public std::bad_alloc
- {
- const char* what() const BOTAN_NOEXCEPT override
- { return "Ran out of memory, allocation failed"; }
- };
-
}
#endif
diff --git a/src/lib/utils/http_util/http_util.cpp b/src/lib/utils/http_util/http_util.cpp
index 1a15d6418..c437d0148 100644
--- a/src/lib/utils/http_util/http_util.cpp
+++ b/src/lib/utils/http_util/http_util.cpp
@@ -30,7 +30,7 @@ std::string http_transact_asio(const std::string& hostname,
tcp.connect(hostname, "http");
if(!tcp)
- throw std::runtime_error("HTTP connection to " + hostname + " failed");
+ throw Exception("HTTP connection to " + hostname + " failed");
tcp << message;
tcp.flush();
@@ -45,7 +45,7 @@ std::string http_transact_asio(const std::string& hostname,
std::string http_transact_fail(const std::string& hostname,
const std::string&)
{
- throw std::runtime_error("Cannot connect to " + hostname +
+ throw Exception("Cannot connect to " + hostname +
": network code disabled in build");
}
@@ -89,7 +89,7 @@ Response http_sync(http_exch_fn http_transact,
{
const auto protocol_host_sep = url.find("://");
if(protocol_host_sep == std::string::npos)
- throw std::runtime_error("Invalid URL " + url);
+ throw Exception("Invalid URL " + url);
const std::string protocol = url.substr(0, protocol_host_sep);
const auto host_loc_sep = url.find('/', protocol_host_sep + 3);
@@ -130,7 +130,7 @@ Response http_sync(http_exch_fn http_transact,
std::string line1;
std::getline(io, line1);
if(!io || line1.empty())
- throw std::runtime_error("No response");
+ throw Exception("No response");
std::stringstream response_stream(line1);
std::string http_version;
@@ -142,7 +142,7 @@ Response http_sync(http_exch_fn http_transact,
std::getline(response_stream, status_message);
if(!response_stream || http_version.substr(0,5) != "HTTP/")
- throw std::runtime_error("Not an HTTP response");
+ throw Exception("Not an HTTP response");
std::map<std::string, std::string> headers;
std::string header_line;
@@ -150,7 +150,7 @@ Response http_sync(http_exch_fn http_transact,
{
auto sep = header_line.find(": ");
if(sep == std::string::npos || sep > header_line.size() - 2)
- throw std::runtime_error("Invalid HTTP header " + header_line);
+ throw Exception("Invalid HTTP header " + header_line);
const std::string key = header_line.substr(0, sep);
if(sep + 2 < header_line.size() - 1)
@@ -163,7 +163,7 @@ Response http_sync(http_exch_fn http_transact,
if(status_code == 301 && headers.count("Location"))
{
if(allowable_redirects == 0)
- throw std::runtime_error("HTTP redirection count exceeded");
+ throw Exception("HTTP redirection count exceeded");
return GET_sync(headers["Location"], allowable_redirects - 1);
}
@@ -180,7 +180,7 @@ Response http_sync(http_exch_fn http_transact,
if(header_size != "")
{
if(resp_body.size() != to_u32bit(header_size))
- throw std::runtime_error("Content-Length disagreement, header says " +
+ throw Exception("Content-Length disagreement, header says " +
header_size + " got " + std::to_string(resp_body.size()));
}
diff --git a/src/lib/utils/http_util/http_util.h b/src/lib/utils/http_util/http_util.h
index 2acb6c6e4..746b790f1 100644
--- a/src/lib/utils/http_util/http_util.h
+++ b/src/lib/utils/http_util/http_util.h
@@ -43,7 +43,7 @@ struct Response
void throw_unless_ok()
{
if(status_code() != 200)
- throw std::runtime_error("HTTP error: " + status_message());
+ throw Exception("HTTP error: " + status_message());
}
private:
diff --git a/src/lib/utils/parsing.cpp b/src/lib/utils/parsing.cpp
index 40eae656a..179e2e546 100644
--- a/src/lib/utils/parsing.cpp
+++ b/src/lib/utils/parsing.cpp
@@ -45,7 +45,7 @@ u32bit to_u32bit(const std::string& str)
auto message = std::string("Could not read '" + str + "' as decimal string");
auto exceptionMessage = std::string(e.what());
if (!exceptionMessage.empty()) message += ": " + exceptionMessage;
- throw std::runtime_error(message);
+ throw Exception(message);
}
}
diff --git a/src/lib/utils/read_cfg.cpp b/src/lib/utils/read_cfg.cpp
index 22e725328..0719ee681 100644
--- a/src/lib/utils/read_cfg.cpp
+++ b/src/lib/utils/read_cfg.cpp
@@ -49,7 +49,7 @@ std::map<std::string, std::string> read_cfg(std::istream& is)
auto eq = s.find("=");
if(eq == std::string::npos || eq == 0 || eq == s.size() - 1)
- throw std::runtime_error("Bad read_cfg input '" + s + "' on line " + std::to_string(line));
+ throw Exception("Bad read_cfg input '" + s + "' on line " + std::to_string(line));
const std::string key = clean_ws(s.substr(0, eq));
const std::string val = clean_ws(s.substr(eq + 1, std::string::npos));
diff --git a/src/lib/utils/sqlite3/sqlite3.cpp b/src/lib/utils/sqlite3/sqlite3.cpp
index 267d7530a..fde89b91d 100644
--- a/src/lib/utils/sqlite3/sqlite3.cpp
+++ b/src/lib/utils/sqlite3/sqlite3.cpp
@@ -20,7 +20,7 @@ Sqlite3_Database::Sqlite3_Database(const std::string& db_filename)
const std::string err_msg = ::sqlite3_errmsg(m_db);
::sqlite3_close(m_db);
m_db = nullptr;
- throw std::runtime_error("sqlite3_open failed - " + err_msg);
+ throw Exception("sqlite3_open failed - " + err_msg);
}
}
@@ -43,7 +43,7 @@ size_t Sqlite3_Database::row_count(const std::string& table_name)
if(stmt->step())
return stmt->get_size_t(0);
else
- throw std::runtime_error("Querying size of table " + table_name + " failed");
+ throw Exception("Querying size of table " + table_name + " failed");
}
void Sqlite3_Database::create_table(const std::string& table_schema)
@@ -57,7 +57,7 @@ void Sqlite3_Database::create_table(const std::string& table_schema)
::sqlite3_free(errmsg);
::sqlite3_close(m_db);
m_db = nullptr;
- throw std::runtime_error("sqlite3_exec for table failed - " + err_msg);
+ throw Exception("sqlite3_exec for table failed - " + err_msg);
}
}
@@ -66,7 +66,7 @@ Sqlite3_Database::Sqlite3_Statement::Sqlite3_Statement(sqlite3* db, const std::s
int rc = ::sqlite3_prepare_v2(db, base_sql.c_str(), -1, &m_stmt, nullptr);
if(rc != SQLITE_OK)
- throw std::runtime_error("sqlite3_prepare failed " + base_sql +
+ throw Exception("sqlite3_prepare failed " + base_sql +
", code " + std::to_string(rc));
}
@@ -74,16 +74,16 @@ void Sqlite3_Database::Sqlite3_Statement::bind(int column, const std::string& va
{
int rc = ::sqlite3_bind_text(m_stmt, column, val.c_str(), -1, SQLITE_TRANSIENT);
if(rc != SQLITE_OK)
- throw std::runtime_error("sqlite3_bind_text failed, code " + std::to_string(rc));
+ throw Exception("sqlite3_bind_text failed, code " + std::to_string(rc));
}
void Sqlite3_Database::Sqlite3_Statement::bind(int column, size_t val)
{
if(val != static_cast<size_t>(static_cast<int>(val))) // is this legit?
- throw std::runtime_error("sqlite3 cannot store " + std::to_string(val) + " without truncation");
+ throw Exception("sqlite3 cannot store " + std::to_string(val) + " without truncation");
int rc = ::sqlite3_bind_int(m_stmt, column, val);
if(rc != SQLITE_OK)
- throw std::runtime_error("sqlite3_bind_int failed, code " + std::to_string(rc));
+ throw Exception("sqlite3_bind_int failed, code " + std::to_string(rc));
}
void Sqlite3_Database::Sqlite3_Statement::bind(int column, std::chrono::system_clock::time_point time)
@@ -96,7 +96,7 @@ void Sqlite3_Database::Sqlite3_Statement::bind(int column, const std::vector<byt
{
int rc = ::sqlite3_bind_blob(m_stmt, column, val.data(), val.size(), SQLITE_TRANSIENT);
if(rc != SQLITE_OK)
- throw std::runtime_error("sqlite3_bind_text failed, code " + std::to_string(rc));
+ throw Exception("sqlite3_bind_text failed, code " + std::to_string(rc));
}
std::pair<const byte*, size_t> Sqlite3_Database::Sqlite3_Statement::get_blob(int column)