MINIFICPP-1408 thrown objects should be derived from std::exception
Signed-off-by: Arpad Boda <aboda@apache.org>
This closes #938
diff --git a/extensions/sftp/client/SFTPClient.cpp b/extensions/sftp/client/SFTPClient.cpp
index c56b327..94861b9 100644
--- a/extensions/sftp/client/SFTPClient.cpp
+++ b/extensions/sftp/client/SFTPClient.cpp
@@ -67,19 +67,19 @@
static SFTPError libssh2_sftp_error_to_sftp_error(unsigned long libssh2_sftp_error) {
switch (libssh2_sftp_error) {
case LIBSSH2_FX_OK:
- return SFTPError::SFTP_ERROR_OK;
+ return SFTPError::Ok;
case LIBSSH2_FX_NO_SUCH_FILE:
case LIBSSH2_FX_NO_SUCH_PATH:
- return SFTPError::SFTP_ERROR_FILE_NOT_EXISTS;
+ return SFTPError::FileDoesNotExist;
case LIBSSH2_FX_FILE_ALREADY_EXISTS:
- return SFTPError::SFTP_ERROR_FILE_ALREADY_EXISTS;
+ return SFTPError::FileAlreadyExists;
case LIBSSH2_FX_PERMISSION_DENIED:
case LIBSSH2_FX_WRITE_PROTECT:
case LIBSSH2_FX_LOCK_CONFLICT:
- return SFTPError::SFTP_ERROR_PERMISSION_DENIED;
+ return SFTPError::PermissionDenied;
case LIBSSH2_FX_NO_CONNECTION:
case LIBSSH2_FX_CONNECTION_LOST:
- return SFTPError::SFTP_ERROR_COMMUNICATIONS_FAILURE;
+ return SFTPError::CommunicationFailure;
case LIBSSH2_FX_EOF:
case LIBSSH2_FX_FAILURE:
case LIBSSH2_FX_BAD_MESSAGE:
@@ -94,7 +94,7 @@
case LIBSSH2_FX_INVALID_FILENAME:
case LIBSSH2_FX_LINK_LOOP:
default:
- return SFTPError::SFTP_ERROR_UNEXPECTED;
+ return SFTPError::Unexpected;
}
}
@@ -103,16 +103,16 @@
LastSFTPError::LastSFTPError()
: sftp_error_set_(false)
, libssh2_sftp_error_(LIBSSH2_FX_OK)
- , sftp_error_(SFTPError::SFTP_ERROR_OK) {
+ , sftp_error_(SFTPError::Ok) {
}
-LastSFTPError& LastSFTPError::operator=(unsigned long libssh2_sftp_error) {
+LastSFTPError& LastSFTPError::setLibssh2Error(unsigned long libssh2_sftp_error) {
sftp_error_set_ = false;
libssh2_sftp_error_ = libssh2_sftp_error;
return *this;
}
-LastSFTPError& LastSFTPError::operator=(const SFTPError& sftp_error) {
+LastSFTPError& LastSFTPError::setSftpError(const SFTPError& sftp_error) {
sftp_error_set_ = true;
sftp_error_ = sftp_error;
return *this;
@@ -140,18 +140,7 @@
hostname_(hostname),
port_(port),
username_(username),
- ssh_known_hosts_(nullptr),
- strict_host_checking_(false),
- password_authentication_enabled_(false),
- public_key_authentication_enabled_(false),
- data_timeout_(0),
- send_keepalive_(false),
- curl_errorbuffer_(CURL_ERROR_SIZE, '\0'),
- easy_(nullptr),
- ssh_session_(nullptr),
- sftp_session_(nullptr),
- connected_(false),
- last_error_() {
+ curl_errorbuffer_(CURL_ERROR_SIZE, '\0') {
easy_ = curl_easy_init();
if (easy_ == nullptr) {
throw std::runtime_error("Cannot create curl easy handle");
@@ -496,10 +485,10 @@
int ssh_errno = libssh2_session_last_errno(ssh_session_);
/* We can only get the sftp error in this case if the ssh error is a protocol error */
if (ssh_errno == LIBSSH2_ERROR_SFTP_PROTOCOL) {
- last_error_ = libssh2_sftp_last_error(sftp_session_);
+ last_error_.setLibssh2Error(libssh2_sftp_last_error(sftp_session_));
logger_->log_error("Failed to open remote file \"%s\", error: %s", path.c_str(), sftp_strerror(last_error_));
} else {
- last_error_ = SFTPError::SFTP_ERROR_IO_ERROR;
+ last_error_.setSftpError(SFTPError::IoError);
char *err_msg = nullptr;
libssh2_session_last_error(ssh_session_, &err_msg, nullptr, 0);
logger_->log_error("Failed to open remote file \"%s\" due to an underlying SSH error: %s", path.c_str(), err_msg);
@@ -516,7 +505,7 @@
do {
ssize_t read_ret = libssh2_sftp_read(file_handle, reinterpret_cast<char*>(buf.data()), buf.size());
if (read_ret < 0) {
- last_error_ = SFTPError::SFTP_ERROR_IO_ERROR;
+ last_error_.setSftpError(SFTPError::IoError);
logger_->log_error("Failed to read remote file \"%s\"", path.c_str());
return false;
} else if (read_ret == 0) {
@@ -529,7 +518,7 @@
while (remaining > 0) {
int write_ret = output.write(buf.data() + (read_ret - remaining), remaining);
if (write_ret < 0) {
- last_error_ = LIBSSH2_FX_OK;
+ last_error_.setLibssh2Error(LIBSSH2_FX_OK);
logger_->log_error("Failed to write output");
return false;
}
@@ -538,7 +527,7 @@
} while (true);
if (expected_size >= 0 && total_read != expected_size) {
- last_error_ = LIBSSH2_FX_OK;
+ last_error_.setLibssh2Error(LIBSSH2_FX_OK);
logger_->log_error("Remote file \"%s\" has unexpected size, expected: %ld, actual: %lu", path.c_str(), expected_size, total_read);
return false;
}
@@ -554,10 +543,10 @@
int ssh_errno = libssh2_session_last_errno(ssh_session_);
/* We can only get the sftp error in this case if the ssh error is a protocol error */
if (ssh_errno == LIBSSH2_ERROR_SFTP_PROTOCOL) {
- last_error_ = libssh2_sftp_last_error(sftp_session_);
+ last_error_.setLibssh2Error(libssh2_sftp_last_error(sftp_session_));
logger_->log_error("Failed to open remote file \"%s\", error: %s", path.c_str(), sftp_strerror(last_error_));
} else {
- last_error_ = SFTPError::SFTP_ERROR_IO_ERROR;
+ last_error_.setSftpError(SFTPError::IoError);
char *err_msg = nullptr;
libssh2_session_last_error(ssh_session_, &err_msg, nullptr, 0);
logger_->log_error("Failed to open remote file \"%s\" due to an underlying SSH error: %s", path.c_str(), err_msg);
@@ -579,7 +568,7 @@
do {
int read_ret = input.read(buf.data(), buf.size());
if (read_ret < 0) {
- last_error_ = LIBSSH2_FX_OK;
+ last_error_.setLibssh2Error(LIBSSH2_FX_OK);
logger_->log_error("Error while reading input");
return false;
} else if (read_ret == 0) {
@@ -592,7 +581,7 @@
while (remaining > 0) {
int write_ret = libssh2_sftp_write(file_handle, reinterpret_cast<char*>(buf.data() + (read_ret - remaining)), remaining);
if (write_ret < 0) {
- last_error_ = SFTPError::SFTP_ERROR_IO_ERROR;
+ last_error_.setSftpError(SFTPError::IoError);
logger_->log_error("Failed to write remote file \"%s\"", path.c_str());
return false;
}
@@ -602,7 +591,7 @@
} while (true);
if (expected_size >= 0 && total_read != expected_size) {
- last_error_ = LIBSSH2_FX_OK;
+ last_error_.setLibssh2Error(LIBSSH2_FX_OK);
logger_->log_error("Input has unexpected size, expected: %ld, actual: %lu", path.c_str(), expected_size, total_read);
return false;
}
@@ -634,7 +623,7 @@
}
continue;
}
- last_error_ = libssh2_sftp_last_error(sftp_session_);
+ last_error_.setLibssh2Error(libssh2_sftp_last_error(sftp_session_));
logger_->log_error("Failed to rename remote file \"%s\" to \"%s\", error: %s",
source_path.c_str(),
target_path.c_str(),
@@ -646,7 +635,7 @@
bool SFTPClient::createDirectoryHierarchy(const std::string& path) {
if (path.empty()) {
- last_error_ = LIBSSH2_FX_OK;
+ last_error_.setLibssh2Error(LIBSSH2_FX_OK);
return false;
}
bool absolute = path[0] == '/';
@@ -664,7 +653,7 @@
if (err != LIBSSH2_FX_FILE_ALREADY_EXISTS &&
err != LIBSSH2_FX_FAILURE &&
err != LIBSSH2_FX_PERMISSION_DENIED) {
- last_error_ = err;
+ last_error_.setLibssh2Error(err);
logger_->log_error("Failed to create remote directory \"%s\", error: %s", current_dir.c_str(), sftp_strerror(last_error_));
return false;
} else {
@@ -677,7 +666,7 @@
bool SFTPClient::removeFile(const std::string& path) {
if (libssh2_sftp_unlink(sftp_session_, path.c_str()) != 0) {
- last_error_ = libssh2_sftp_last_error(sftp_session_);
+ last_error_.setLibssh2Error(libssh2_sftp_last_error(sftp_session_));
logger_->log_error("Failed to remove remote file \"%s\", error: %s", path.c_str(), sftp_strerror(last_error_));
return false;
}
@@ -686,7 +675,7 @@
bool SFTPClient::removeDirectory(const std::string& path) {
if (libssh2_sftp_rmdir(sftp_session_, path.c_str()) != 0) {
- last_error_ = libssh2_sftp_last_error(sftp_session_);
+ last_error_.setLibssh2Error(libssh2_sftp_last_error(sftp_session_));
logger_->log_error("Failed to remove remote directory \"%s\", error: %s", path.c_str(), sftp_strerror(last_error_));
return false;
}
@@ -702,7 +691,7 @@
0 /* mode */,
LIBSSH2_SFTP_OPENDIR);
if (dir_handle == nullptr) {
- last_error_ = libssh2_sftp_last_error(sftp_session_);
+ last_error_.setLibssh2Error(libssh2_sftp_last_error(sftp_session_));
logger_->log_error("Failed to open remote directory \"%s\", error: %s", path.c_str(), sftp_strerror(last_error_));
return false;
}
@@ -721,7 +710,7 @@
longentry.size(),
&attrs);
if (ret < 0) {
- last_error_ = libssh2_sftp_last_error(sftp_session_);
+ last_error_.setLibssh2Error(libssh2_sftp_last_error(sftp_session_));
logger_->log_error("Failed to read remote directory \"%s\", error: %s", path.c_str(), sftp_strerror(last_error_));
return false;
} else if (ret == 0) {
@@ -746,7 +735,7 @@
path.length(),
follow_symlinks ? LIBSSH2_SFTP_STAT : LIBSSH2_SFTP_LSTAT,
&result) != 0) {
- last_error_ = libssh2_sftp_last_error(sftp_session_);
+ last_error_.setLibssh2Error(libssh2_sftp_last_error(sftp_session_));
logger_->log_debug("Failed to stat remote path \"%s\", error: %s", path.c_str(), sftp_strerror(last_error_));
return false;
}
@@ -790,7 +779,7 @@
path.length(),
LIBSSH2_SFTP_SETSTAT,
&attrs) != 0) {
- last_error_ = libssh2_sftp_last_error(sftp_session_);
+ last_error_.setLibssh2Error(libssh2_sftp_last_error(sftp_session_));
logger_->log_debug("Failed to setstat on remote path \"%s\", error: %s", path.c_str(), sftp_strerror(last_error_));
return false;
}
diff --git a/extensions/sftp/client/SFTPClient.h b/extensions/sftp/client/SFTPClient.h
index 6bf2af8..aba8307 100644
--- a/extensions/sftp/client/SFTPClient.h
+++ b/extensions/sftp/client/SFTPClient.h
@@ -26,6 +26,8 @@
#include <string>
#include <vector>
+#include "Exception.h"
+#include "utils/Enum.h"
#include "utils/HTTPClient.h"
#include "core/logging/Logger.h"
#include "core/logging/LoggerConfiguration.h"
@@ -39,14 +41,24 @@
namespace minifi {
namespace utils {
-enum class SFTPError : uint8_t {
- SFTP_ERROR_OK = 0,
- SFTP_ERROR_PERMISSION_DENIED,
- SFTP_ERROR_FILE_NOT_EXISTS,
- SFTP_ERROR_FILE_ALREADY_EXISTS,
- SFTP_ERROR_COMMUNICATIONS_FAILURE,
- SFTP_ERROR_IO_ERROR,
- SFTP_ERROR_UNEXPECTED
+SMART_ENUM(SFTPError,
+ (Ok, "Ok"),
+ (PermissionDenied, "Permission denied"),
+ (FileDoesNotExist, "File does not exist"),
+ (FileAlreadyExists, "File already exists"),
+ (CommunicationFailure, "Communication failure"),
+ (IoError, "IO error"),
+ (Unexpected, "Unexpected"));
+
+class SFTPException : public Exception {
+ public:
+ explicit SFTPException(const SFTPError err)
+ :Exception{ExceptionType::FILE_OPERATION_EXCEPTION, fmt::format("SFTP Error: {0}", err.toString())},
+ error_{err}
+ {}
+ SFTPError error() const noexcept { return error_; }
+ private:
+ SFTPError error_;
};
class LastSFTPError {
@@ -58,8 +70,8 @@
LastSFTPError& operator=(const LastSFTPError&) = delete;
LastSFTPError& operator=(LastSFTPError&&) = delete;
- LastSFTPError& operator=(unsigned long libssh2_sftp_error);
- LastSFTPError& operator=(const SFTPError& sftp_error);
+ LastSFTPError& setLibssh2Error(unsigned long libssh2_sftp_error);
+ LastSFTPError& setSftpError(const SFTPError& sftp_error);
operator unsigned long() const;
operator SFTPError() const;
@@ -148,7 +160,6 @@
bool setAttributes(const std::string& path, const SFTPAttributes& attrs);
protected:
-
/*
* The maximum size libssh2 is willing to read or write in one go is 30000 bytes.
* (See MAX_SFTP_OUTGOING_SIZE and MAX_SFTP_READ_SIZE).
@@ -162,27 +173,27 @@
const uint16_t port_;
const std::string username_;
- LIBSSH2_KNOWNHOSTS *ssh_known_hosts_;
- bool strict_host_checking_;
+ LIBSSH2_KNOWNHOSTS *ssh_known_hosts_ = nullptr;
+ bool strict_host_checking_ = false;
- bool password_authentication_enabled_;
+ bool password_authentication_enabled_ = false;
std::string password_;
- bool public_key_authentication_enabled_;
+ bool public_key_authentication_enabled_ = false;
std::string private_key_file_path_;
std::string private_key_passphrase_;
- int64_t data_timeout_;
+ int64_t data_timeout_ = 0;
- bool send_keepalive_;
+ bool send_keepalive_ = false;
std::vector<char> curl_errorbuffer_;
- CURL *easy_;
- LIBSSH2_SESSION *ssh_session_;
- LIBSSH2_SFTP *sftp_session_;
+ CURL *easy_ = nullptr;
+ LIBSSH2_SESSION *ssh_session_ = nullptr;
+ LIBSSH2_SFTP *sftp_session_ = nullptr;
- bool connected_;
+ bool connected_ = false;
LastSFTPError last_error_;
};
diff --git a/extensions/sftp/processors/FetchSFTP.cpp b/extensions/sftp/processors/FetchSFTP.cpp
index d5bc1f9..560e98f 100644
--- a/extensions/sftp/processors/FetchSFTP.cpp
+++ b/extensions/sftp/processors/FetchSFTP.cpp
@@ -159,7 +159,7 @@
int64_t FetchSFTP::WriteCallback::process(const std::shared_ptr<io::BaseStream>& stream) {
if (!client_.getFile(remote_file_, *stream)) {
- throw client_.getLastError();
+ throw utils::SFTPException{client_.getLastError()};
}
return stream->size();
}
@@ -214,18 +214,19 @@
WriteCallback write_callback(remote_file, *client);
try {
session->write(flow_file, &write_callback);
- } catch (const utils::SFTPError& error) {
- switch (error) {
- case utils::SFTPError::SFTP_ERROR_PERMISSION_DENIED:
+ } catch (const utils::SFTPException& ex) {
+ logger_->log_debug(ex.what());
+ switch (ex.error().value()) {
+ case utils::SFTPError::PermissionDenied:
session->transfer(flow_file, PermissionDenied);
put_connection_back_to_cache();
return;
- case utils::SFTPError::SFTP_ERROR_FILE_NOT_EXISTS:
+ case utils::SFTPError::FileDoesNotExist:
session->transfer(flow_file, NotFound);
put_connection_back_to_cache();
return;
- case utils::SFTPError::SFTP_ERROR_COMMUNICATIONS_FAILURE:
- case utils::SFTPError::SFTP_ERROR_IO_ERROR:
+ case utils::SFTPError::CommunicationFailure:
+ case utils::SFTPError::IoError:
session->transfer(flow_file, CommsFailure);
return;
default:
diff --git a/extensions/sftp/processors/PutSFTP.cpp b/extensions/sftp/processors/PutSFTP.cpp
index e9c1a8f..1cb6115 100644
--- a/extensions/sftp/processors/PutSFTP.cpp
+++ b/extensions/sftp/processors/PutSFTP.cpp
@@ -215,7 +215,7 @@
*stream,
conflict_resolution_ == CONFLICT_RESOLUTION_REPLACE /*overwrite*/,
stream->size() /*expected_size*/)) {
- throw client_.getLastError();
+ throw utils::SFTPException{client_.getLastError()};
}
return stream->size();
}
@@ -325,7 +325,7 @@
std::string target_path = utils::file::FileUtils::concat_path(remote_path, filename, true /*force_posix*/);
LIBSSH2_SFTP_ATTRIBUTES attrs;
if (!client->stat(target_path, true /*follow_symlinks*/, attrs)) {
- if (client->getLastError() != utils::SFTPError::SFTP_ERROR_FILE_NOT_EXISTS) {
+ if (client->getLastError() != utils::SFTPError::FileDoesNotExist) {
logger_->log_error("Failed to stat %s", target_path.c_str());
session->transfer(flow_file, Failure);
return true;
@@ -362,7 +362,7 @@
possible_resolved_filename = possible_resolved_filename_ss.str();
std::string possible_resolved_path = utils::file::FileUtils::concat_path(remote_path, possible_resolved_filename, true /*force_posix*/);
if (!client->stat(possible_resolved_path, true /*follow_symlinks*/, attrs)) {
- if (client->getLastError() == utils::SFTPError::SFTP_ERROR_FILE_NOT_EXISTS) {
+ if (client->getLastError() == utils::SFTPError::FileDoesNotExist) {
unique_name_generated = true;
break;
} else {
@@ -427,7 +427,8 @@
ReadCallback read_callback(target_path.c_str(), *client, conflict_resolution_);
try {
session->read(flow_file, &read_callback);
- } catch (const utils::SFTPError&) {
+ } catch (const utils::SFTPException& ex) {
+ logger_->log_debug(ex.what());
session->transfer(flow_file, Failure);
return true;
}
diff --git a/extensions/sftp/processors/SFTPProcessorBase.cpp b/extensions/sftp/processors/SFTPProcessorBase.cpp
index 97f0449..96e97d5 100644
--- a/extensions/sftp/processors/SFTPProcessorBase.cpp
+++ b/extensions/sftp/processors/SFTPProcessorBase.cpp
@@ -430,7 +430,7 @@
if (!disable_directory_listing) {
LIBSSH2_SFTP_ATTRIBUTES attrs;
if (!client.stat(remote_path, true /*follow_symlinks*/, attrs)) {
- if (client.getLastError() != utils::SFTPError::SFTP_ERROR_FILE_NOT_EXISTS) {
+ if (client.getLastError() != utils::SFTPError::FileDoesNotExist) {
logger_->log_error("Failed to stat %s", remote_path.c_str());
}
should_create_directory = true;
@@ -448,10 +448,10 @@
LIBSSH2_SFTP_ATTRIBUTES attrs;
if (!client.stat(remote_path, true /*follow_symlinks*/, attrs)) {
auto last_error = client.getLastError();
- if (last_error == utils::SFTPError::SFTP_ERROR_FILE_NOT_EXISTS) {
+ if (last_error == utils::SFTPError::FileDoesNotExist) {
logger_->log_error("Could not find remote directory %s after creating it", remote_path.c_str());
return CreateDirectoryHierarchyError::CREATE_DIRECTORY_HIERARCHY_ERROR_NOT_FOUND;
- } else if (last_error == utils::SFTPError::SFTP_ERROR_PERMISSION_DENIED) {
+ } else if (last_error == utils::SFTPError::PermissionDenied) {
logger_->log_error("Permission denied when reading remote directory %s after creating it", remote_path.c_str());
return CreateDirectoryHierarchyError::CREATE_DIRECTORY_HIERARCHY_ERROR_PERMISSION_DENIED;
} else {
diff --git a/libminifi/src/core/yaml/YamlConfiguration.cpp b/libminifi/src/core/yaml/YamlConfiguration.cpp
index 3c80f37..a53c0db 100644
--- a/libminifi/src/core/yaml/YamlConfiguration.cpp
+++ b/libminifi/src/core/yaml/YamlConfiguration.cpp
@@ -250,11 +250,10 @@
parentGroup->addProcessor(processor);
}
} else {
- throw new std::invalid_argument("Cannot instantiate a MiNiFi instance without a defined Processors configuration node.");
+ throw std::invalid_argument("Cannot instantiate a MiNiFi instance without a defined Processors configuration node.");
}
} else {
- throw new std::invalid_argument("Cannot instantiate a MiNiFi instance without a defined "
- "Processors configuration node.");
+ throw std::invalid_argument("Cannot instantiate a MiNiFi instance without a defined Processors configuration node.");
}
}
diff --git a/libminifi/test/RandomServerSocket.cpp b/libminifi/test/RandomServerSocket.cpp
index f912fbb..a532f44 100644
--- a/libminifi/test/RandomServerSocket.cpp
+++ b/libminifi/test/RandomServerSocket.cpp
@@ -27,6 +27,7 @@
#include <string>
#include <memory>
+#include "Exception.h"
#include "core/logging/Logger.h"
#include "core/logging/LoggerConfiguration.h"
@@ -44,7 +45,7 @@
auto logger = logging::LoggerFactory<RandomServerSocket>::getLogger();
for (uint16_t i = 0; i < retries; ++i) {
setPort(dis(gen));
- if (initialize() == 0) {
+ if (RandomServerSocket::initialize() == 0) {
logger->log_info("Created socket listens on generated port: %hu", getPort());
return;
}
@@ -52,7 +53,7 @@
std::stringstream error;
error << "Couldn't bind to a port between " << offset << " and " << offset+range << " in " << retries << " try!";
logger->log_error(error.str().c_str());
- throw error.str();
+ throw Exception{ExceptionType::GENERAL_EXCEPTION, error.str()};
}
} /* namespace io */