Skip to content

Commit

Permalink
Merge pull request #164 from itrofimow/exceptions_hierarchy
Browse files Browse the repository at this point in the history
introduce exceptions hierarchy
  • Loading branch information
Enmk authored Apr 13, 2022
2 parents b2e5da9 + 293981d commit 898ac2a
Show file tree
Hide file tree
Showing 24 changed files with 147 additions and 102 deletions.
15 changes: 8 additions & 7 deletions clickhouse/base/compressed.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "compressed.h"
#include "wire_format.h"
#include "output.h"
#include "../exceptions.h"

#include <cityhash/city.h>
#include <lz4/lz4.h>
Expand Down Expand Up @@ -30,7 +31,7 @@ CompressedInput::~CompressedInput() {
#else
if (!std::uncaught_exceptions()) {
#endif
throw std::runtime_error("some data was not read");
throw LZ4Error("some data was not read");
}
}
}
Expand Down Expand Up @@ -59,7 +60,7 @@ bool CompressedInput::Decompress() {
}

if (method != COMPRESSION_METHOD) {
throw std::runtime_error("unsupported compression method " + std::to_string(int(method)));
throw LZ4Error("unsupported compression method " + std::to_string(int(method)));
} else {
if (!WireFormat::ReadFixed(*input_, &compressed)) {
return false;
Expand All @@ -69,7 +70,7 @@ bool CompressedInput::Decompress() {
}

if (compressed > DBMS_MAX_COMPRESSED_SIZE) {
throw std::runtime_error("compressed data too big");
throw LZ4Error("compressed data too big");
}

Buffer tmp(compressed);
Expand All @@ -87,14 +88,14 @@ bool CompressedInput::Decompress() {
return false;
} else {
if (hash != CityHash128((const char*)tmp.data(), compressed)) {
throw std::runtime_error("data was corrupted");
throw LZ4Error("data was corrupted");
}
}

data_ = Buffer(original);

if (LZ4_decompress_safe((const char*)tmp.data() + HEADER_SIZE, (char*)data_.data(), compressed - HEADER_SIZE, original) < 0) {
throw std::runtime_error("can't decompress data");
throw LZ4Error("can't decompress data");
} else {
mem_.Reset(data_.data(), original);
}
Expand Down Expand Up @@ -143,7 +144,7 @@ void CompressedOutput::Compress(const void * data, size_t len) {
len,
static_cast<int>(compressed_buffer_.size() - HEADER_SIZE));
if (compressed_size <= 0)
throw std::runtime_error("Failed to compress chunk of " + std::to_string(len) + " bytes, "
throw LZ4Error("Failed to compress chunk of " + std::to_string(len) + " bytes, "
"LZ4 error: " + std::to_string(compressed_size));

{
Expand All @@ -165,7 +166,7 @@ void CompressedOutput::Compress(const void * data, size_t len) {
void CompressedOutput::PreallocateCompressBuffer(size_t input_size) {
const auto estimated_compressed_buffer_size = LZ4_compressBound(static_cast<int>(input_size));
if (estimated_compressed_buffer_size <= 0)
throw std::runtime_error("Failed to estimate compressed buffer size, LZ4 error: " + std::to_string(estimated_compressed_buffer_size));
throw LZ4Error("Failed to estimate compressed buffer size, LZ4 error: " + std::to_string(estimated_compressed_buffer_size));

compressed_buffer_.resize(estimated_compressed_buffer_size + HEADER_SIZE + EXTRA_COMPRESS_BUFFER_SIZE);
}
Expand Down
17 changes: 9 additions & 8 deletions clickhouse/base/sslsocket.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "sslsocket.h"
#include "../client.h"
#include "../exceptions.h"

#include <stdexcept>

Expand Down Expand Up @@ -45,7 +46,7 @@ void throwSSLError(SSL * ssl, int error, const char * /*location*/, const char *
// << "\n\t last err: " << ERR_peek_last_error()
// << std::endl;

throw std::runtime_error(prefix + std::to_string(error) + " : " + reason_str);
throw clickhouse::OpenSSLError(prefix + std::to_string(error) + " : " + reason_str);
}

void configureSSL(const clickhouse::SSLParams::ConfigurationType & configuration, SSL * ssl, SSL_CTX * context = nullptr) {
Expand Down Expand Up @@ -75,13 +76,13 @@ void configureSSL(const clickhouse::SSLParams::ConfigurationType & configuration
else if (err == 0)
throwSSLError(ssl, SSL_ERROR_NONE, nullptr, nullptr, "Failed to configure OpenSSL with command '" + kv.first + "' ");
else if (err == 1 && value_present)
throw std::runtime_error("Failed to configure OpenSSL: command '" + kv.first + "' needs no value");
throw clickhouse::OpenSSLError("Failed to configure OpenSSL: command '" + kv.first + "' needs no value");
else if (err == -2)
throw std::runtime_error("Failed to cofigure OpenSSL: unknown command '" + kv.first + "'");
throw clickhouse::OpenSSLError("Failed to cofigure OpenSSL: unknown command '" + kv.first + "'");
else if (err == -3)
throw std::runtime_error("Failed to cofigure OpenSSL: command '" + kv.first + "' requires a value");
throw clickhouse::OpenSSLError("Failed to cofigure OpenSSL: command '" + kv.first + "' requires a value");
else
throw std::runtime_error("Failed to cofigure OpenSSL: command '" + kv.first + "' unknown error: " + std::to_string(err));
throw clickhouse::OpenSSLError("Failed to cofigure OpenSSL: command '" + kv.first + "' unknown error: " + std::to_string(err));
}
}

Expand All @@ -104,7 +105,7 @@ SSL_CTX * prepareSSLContext(const clickhouse::SSLParams & context_params) {
std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)> ctx(SSL_CTX_new(method), &SSL_CTX_free);

if (!ctx)
throw std::runtime_error("Failed to initialize SSL context");
throw clickhouse::OpenSSLError("Failed to initialize SSL context");

#define HANDLE_SSL_CTX_ERROR(statement) do { \
if (const auto ret_code = (statement); !ret_code) \
Expand Down Expand Up @@ -204,7 +205,7 @@ SSLSocket::SSLSocket(const NetworkAddress& addr, const SSLParams & ssl_params,
{
auto ssl = ssl_.get();
if (!ssl)
throw std::runtime_error("Failed to create SSL instance");
throw clickhouse::OpenSSLError("Failed to create SSL instance");

std::unique_ptr<ASN1_OCTET_STRING, decltype(&ASN1_OCTET_STRING_free)> ip_addr(a2i_IPADDRESS(addr.Host().c_str()), &ASN1_OCTET_STRING_free);

Expand All @@ -228,7 +229,7 @@ SSLSocket::SSLSocket(const NetworkAddress& addr, const SSLParams & ssl_params,

if (const auto verify_result = SSL_get_verify_result(ssl); !ssl_params.skip_verification && verify_result != X509_V_OK) {
auto error_message = X509_verify_cert_error_string(verify_result);
throw std::runtime_error("Failed to verify SSL connection, X509_v error: "
throw clickhouse::OpenSSLError("Failed to verify SSL connection, X509_v error: "
+ std::to_string(verify_result)
+ " " + error_message
+ "\nServer certificate: " + getCertificateInfo(SSL_get_peer_certificate(ssl)));
Expand Down
4 changes: 3 additions & 1 deletion clickhouse/base/wire_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "input.h"
#include "output.h"

#include "../exceptions.h"

#include <stdexcept>

namespace {
Expand Down Expand Up @@ -38,7 +40,7 @@ void WireFormat::WriteAll(OutputStream& output, const void* buf, size_t len) {
}

if (len) {
throw std::runtime_error("Failed to write " + std::to_string(original_len)
throw Error("Failed to write " + std::to_string(original_len)
+ " bytes, only written " + std::to_string(original_len - len));
}
}
Expand Down
6 changes: 4 additions & 2 deletions clickhouse/block.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "block.h"

#include "exceptions.h"

#include <stdexcept>

namespace clickhouse {
Expand Down Expand Up @@ -54,7 +56,7 @@ void Block::AppendColumn(const std::string& name, const ColumnRef& col) {
if (columns_.empty()) {
rows_ = col->Size();
} else if (col->Size() != rows_) {
throw std::runtime_error("all columns in block must have same count of rows. Name: ["+name+"], rows: ["+std::to_string(rows_)+"], columns: [" + std::to_string(col->Size())+"]");
throw ValidationError("all columns in block must have same count of rows. Name: ["+name+"], rows: ["+std::to_string(rows_)+"], columns: [" + std::to_string(col->Size())+"]");
}

columns_.push_back(ColumnItem{name, col});
Expand Down Expand Up @@ -86,7 +88,7 @@ size_t Block::RefreshRowCount()
if (idx == 0UL)
rows = col->Size();
else if (rows != col->Size())
throw std::runtime_error("all columns in block must have same count of rows. Name: ["+name+"], rows: ["+std::to_string(rows)+"], columns: [" + std::to_string(col->Size())+"]");
throw ValidationError("all columns in block must have same count of rows. Name: ["+name+"], rows: ["+std::to_string(rows)+"], columns: [" + std::to_string(col->Size())+"]");
}

rows_ = rows;
Expand Down
38 changes: 17 additions & 21 deletions clickhouse/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ ClientOptions& ClientOptions::SetSSLOptions(ClientOptions::SSLOptions options)
return *this;
#else
(void)options;
throw std::runtime_error("Library was built with no SSL support");
throw OpenSSLError("Library was built with no SSL support");
#endif
}

Expand Down Expand Up @@ -152,7 +152,7 @@ class Client::Impl {
private:
/// In case of network errors tries to reconnect to server and
/// call fuc several times.
void RetryGuard(std::function<void()> fuc);
void RetryGuard(std::function<void()> func);

private:
class EnsureNull {
Expand Down Expand Up @@ -187,10 +187,6 @@ class Client::Impl {
std::unique_ptr<OutputStream> output_;
std::unique_ptr<SocketBase> socket_;

#if defined(WITH_OPENSSL)
std::unique_ptr<SSLContext> ssl_context_;
#endif

ServerInfo server_info_;
};

Expand Down Expand Up @@ -282,7 +278,7 @@ void Client::Impl::Insert(const std::string& table_name, const std::string& quer
bool ret = ReceivePacket(&server_packet);

if (!ret) {
throw std::runtime_error("fail to receive data packet");
throw ProtocolError("fail to receive data packet");
}
if (server_packet == ServerCodes::Data) {
break;
Expand All @@ -306,7 +302,7 @@ void Client::Impl::Insert(const std::string& table_name, const std::string& quer

if (eos_packet != ServerCodes::EndOfStream && eos_packet != ServerCodes::Exception
&& eos_packet != ServerCodes::Log && options_.rethrow_exceptions) {
throw std::runtime_error(std::string{"unexpected packet from server while receiving end of query, expected (expected Exception, EndOfStream or Log, got: "}
throw ProtocolError(std::string{"unexpected packet from server while receiving end of query, expected (expected Exception, EndOfStream or Log, got: "}
+ (eos_packet ? std::to_string(eos_packet) : "nothing") + ")");
}
}
Expand All @@ -319,15 +315,15 @@ void Client::Impl::Ping() {
const bool ret = ReceivePacket(&server_packet);

if (!ret || server_packet != ServerCodes::Pong) {
throw std::runtime_error("fail to ping server");
throw ProtocolError("fail to ping server");
}
}

void Client::Impl::ResetConnection() {
InitializeStreams(socket_factory_->connect(options_));

if (!Handshake()) {
throw std::runtime_error("fail to connect to " + options_.host);
throw ProtocolError("fail to connect to " + options_.host);
}
}

Expand Down Expand Up @@ -358,7 +354,7 @@ bool Client::Impl::ReceivePacket(uint64_t* server_packet) {
switch (packet_type) {
case ServerCodes::Data: {
if (!ReceiveData()) {
throw std::runtime_error("can't read data packet from input stream");
throw ProtocolError("can't read data packet from input stream");
}
return true;
}
Expand Down Expand Up @@ -431,7 +427,7 @@ bool Client::Impl::ReceivePacket(uint64_t* server_packet) {
}

default:
throw std::runtime_error("unimplemented " + std::to_string((int)packet_type));
throw UnimplementedError("unimplemented " + std::to_string((int)packet_type));
break;
}

Expand Down Expand Up @@ -489,12 +485,12 @@ bool Client::Impl::ReadBlock(InputStream& input, Block* block) {

if (ColumnRef col = CreateColumnByType(type, create_column_settings)) {
if (num_rows && !col->Load(&input, num_rows)) {
throw std::runtime_error("can't load column '" + name + "' of type " + type);
throw ProtocolError("can't load column '" + name + "' of type " + type);
}

block->AppendColumn(name, col);
} else {
throw std::runtime_error(std::string("unsupported column type: ") + type);
throw UnimplementedError(std::string("unsupported column type: ") + type);
}
}

Expand Down Expand Up @@ -573,7 +569,7 @@ bool Client::Impl::ReceiveException(bool rethrow) {
}

if (rethrow || options_.rethrow_exceptions) {
throw ServerException(std::move(e));
throw ServerError(std::move(e));
}

return exception_received;
Expand Down Expand Up @@ -668,8 +664,8 @@ void Client::Impl::SendData(const Block& block) {
if (compression_ == CompressionState::Enable) {
assert(options_.compression_method == CompressionMethod::LZ4);

std::unique_ptr<OutputStream> compressed_ouput = std::make_unique<CompressedOutput>(output_.get(), options_.max_compression_chunk_size);
BufferedOutput buffered(std::move(compressed_ouput), options_.max_compression_chunk_size);
std::unique_ptr<OutputStream> compressed_output = std::make_unique<CompressedOutput>(output_.get(), options_.max_compression_chunk_size);
BufferedOutput buffered(std::move(compressed_output), options_.max_compression_chunk_size);

WriteBlock(block, buffered);
} else {
Expand Down Expand Up @@ -794,19 +790,19 @@ void Client::Execute(const Query& query) {
}

void Client::Select(const std::string& query, SelectCallback cb) {
Execute(Query(query).OnData(cb));
Execute(Query(query).OnData(std::move(cb)));
}

void Client::Select(const std::string& query, const std::string& query_id, SelectCallback cb) {
Execute(Query(query, query_id).OnData(cb));
Execute(Query(query, query_id).OnData(std::move(cb)));
}

void Client::SelectCancelable(const std::string& query, SelectCancelableCallback cb) {
Execute(Query(query).OnDataCancelable(cb));
Execute(Query(query).OnDataCancelable(std::move(cb)));
}

void Client::SelectCancelable(const std::string& query, const std::string& query_id, SelectCancelableCallback cb) {
Execute(Query(query, query_id).OnDataCancelable(cb));
Execute(Query(query, query_id).OnDataCancelable(std::move(cb)));
}

void Client::Select(const Query& query) {
Expand Down
2 changes: 1 addition & 1 deletion clickhouse/columns/array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ ColumnArray::ColumnArray(ColumnRef data)

void ColumnArray::AppendAsColumn(ColumnRef array) {
if (!data_->Type()->IsEqual(array->Type())) {
throw std::runtime_error(
throw ValidationError(
"can't append column of type " + array->Type()->GetName() + " "
"to column type " + data_->Type()->GetName());
}
Expand Down
3 changes: 2 additions & 1 deletion clickhouse/columns/column.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "../types/types.h"
#include "../columns/itemview.h"
#include "../exceptions.h"

#include <memory>
#include <stdexcept>
Expand Down Expand Up @@ -61,7 +62,7 @@ class Column : public std::enable_shared_from_this<Column> {
/// Get a view on raw item data if it is supported by column, will throw an exception if index is out of range.
/// Please note that view is invalidated once column items are added or deleted, column is loaded from strean or destroyed.
virtual ItemView GetItem(size_t) const {
throw std::runtime_error("GetItem() is not supported for column of " + type_->GetName());
throw UnimplementedError("GetItem() is not supported for column of " + type_->GetName());
}

friend void swap(Column& left, Column& right) {
Expand Down
2 changes: 1 addition & 1 deletion clickhouse/columns/date.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ ItemView ColumnDateTime64::GetItem(size_t index) const {
void ColumnDateTime64::Swap(Column& other) {
auto& col = dynamic_cast<ColumnDateTime64&>(other);
if (col.GetPrecision() != GetPrecision()) {
throw std::runtime_error("Can't swap DateTime64 columns when precisions are not the same: "
throw ValidationError("Can't swap DateTime64 columns when precisions are not the same: "
+ std::to_string(GetPrecision()) + "(this) != " + std::to_string(col.GetPrecision()) + "(that)");
}

Expand Down
10 changes: 5 additions & 5 deletions clickhouse/columns/decimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,21 @@ void ColumnDecimal::Append(const std::string& value) {
} else if (*c >= '0' && *c <= '9') {
if (mulOverflow(int_value, 10, &int_value) ||
addOverflow(int_value, *c - '0', &int_value)) {
throw std::runtime_error("value is too big for 128-bit integer");
throw AssertionError("value is too big for 128-bit integer");
}
} else {
throw std::runtime_error(std::string("unexpected symbol '") + (*c) + "' in decimal value");
throw ValidationError(std::string("unexpected symbol '") + (*c) + "' in decimal value");
}
++c;
}

if (c != end) {
throw std::runtime_error("unexpected symbol '-' in decimal value");
throw ValidationError("unexpected symbol '-' in decimal value");
}

while (zeros) {
if (mulOverflow(int_value, 10, &int_value)) {
throw std::runtime_error("value is too big for 128-bit integer");
throw AssertionError("value is too big for 128-bit integer");
}
--zeros;
}
Expand All @@ -187,7 +187,7 @@ Int128 ColumnDecimal::At(size_t i) const {
case Type::Int128:
return data_->As<ColumnInt128>()->At(i);
default:
throw std::runtime_error("Invalid data_ column type in ColumnDecimal");
throw ValidationError("Invalid data_ column type in ColumnDecimal");
}
}

Expand Down
Loading

0 comments on commit 898ac2a

Please sign in to comment.