1
0
Fork 0

make arangorestore not report errors about the target database not found (#5286)

* make arangorestore not report errors about the target database not found

when it is invoked with option `--create-database true`. In this case,
arangorestore should not print an error but simply create the target
database. This patch implements this change.

Additionally, it aborts the startup of arangorestore in case there are
any errors. Previously, the startup phase went on even when no connection
could be established, which led to useless follow-up errors being printed.

* simplify error handling a bit
This commit is contained in:
Jan 2018-05-11 08:31:44 +02:00 committed by GitHub
parent e1da502c67
commit 3c39337d34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 36 deletions

View File

@ -911,14 +911,14 @@ void DumpFeature::start() {
auto dbName = client->databaseName();
// get a client to use in main thread
auto httpClient = _clientManager.getConnectedClient(_options.force, true);
auto httpClient = _clientManager.getConnectedClient(_options.force, true, true);
// check if we are in cluster or single-server mode
Result result{TRI_ERROR_NO_ERROR};
std::tie(result, _options.clusterMode) =
_clientManager.getArangoIsCluster(*httpClient);
if (result.fail()) {
LOG_TOPIC(ERR, Logger::FIXME)
LOG_TOPIC(FATAL, Logger::FIXME)
<< "Error: could not detect ArangoDB instance type";
FATAL_ERROR_EXIT();
}

View File

@ -771,7 +771,7 @@ void RestoreFeature::validateOptions(
if (1 == n) {
_options.inputPath = positionals[0];
} else if (1 < n) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
LOG_TOPIC(FATAL, arangodb::Logger::RESTORE)
<< "expecting at most one directory, got " + join(positionals, ", ");
FATAL_ERROR_EXIT();
}
@ -784,7 +784,7 @@ void RestoreFeature::validateOptions(
auto clamped = boost::algorithm::clamp(_options.threadCount, 1,
4 * TRI_numberProcessors());
if (_options.threadCount != clamped) {
LOG_TOPIC(WARN, Logger::FIXME) << "capping --threads value to " << clamped;
LOG_TOPIC(WARN, Logger::RESTORE) << "capping --threads value to " << clamped;
_options.threadCount = clamped;
}
}
@ -799,7 +799,7 @@ void RestoreFeature::prepare() {
}
if (!_options.importStructure && !_options.importData) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
LOG_TOPIC(FATAL, arangodb::Logger::RESTORE)
<< "Error: must specify either --create-collection or --import-data";
FATAL_ERROR_EXIT();
}
@ -816,11 +816,11 @@ void RestoreFeature::start() {
if (_directory->status().fail()) {
switch (_directory->status().errorNumber()) {
case TRI_ERROR_FILE_NOT_FOUND:
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
LOG_TOPIC(FATAL, arangodb::Logger::RESTORE)
<< "input directory '" << _options.inputPath << "' does not exist";
break;
default:
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
LOG_TOPIC(FATAL, arangodb::Logger::RESTORE)
<< _directory->status().errorMessage();
break;
}
@ -835,7 +835,7 @@ void RestoreFeature::start() {
std::unique_ptr<SimpleHttpClient> httpClient;
Result result =
_clientManager.getConnectedClient(httpClient, _options.force, true);
_clientManager.getConnectedClient(httpClient, _options.force, true, !_options.createDatabase);
if (result.is(TRI_SIMPLE_CLIENT_COULD_NOT_CONNECT)) {
LOG_TOPIC(FATAL, Logger::RESTORE)
<< "cannot create server connection, giving up!";
@ -861,13 +861,12 @@ void RestoreFeature::start() {
// re-check connection and version
result =
_clientManager.getConnectedClient(httpClient, _options.force, true);
if (result.fail() &&
!(_options.force && result.is(TRI_ERROR_INCOMPATIBLE_VERSION))) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "cannot create server connection, giving up!";
FATAL_ERROR_EXIT();
}
_clientManager.getConnectedClient(httpClient, _options.force, true, true);
}
if (result.fail() && !_options.force) {
LOG_TOPIC(FATAL, Logger::RESTORE) << "cannot create server connection: " << result.errorMessage();
FATAL_ERROR_EXIT();
}
// read encryption info
@ -876,7 +875,7 @@ void RestoreFeature::start() {
// read dump info
result = ::checkDumpDatabase(*_directory, _options.forceSameDatabase);
if (result.fail()) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << result.errorMessage();
LOG_TOPIC(FATAL, arangodb::Logger::RESTORE) << result.errorMessage();
FATAL_ERROR_EXIT();
}
@ -884,7 +883,7 @@ void RestoreFeature::start() {
std::tie(result, _options.clusterMode) =
_clientManager.getArangoIsCluster(*httpClient);
if (result.fail()) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << result.errorMessage();
LOG_TOPIC(ERR, arangodb::Logger::RESTORE) << result.errorMessage();
_exitCode = EXIT_FAILURE;
return;
}
@ -892,7 +891,7 @@ void RestoreFeature::start() {
std::tie(result, _options.indexesFirst) =
_clientManager.getArangoIsUsingEngine(*httpClient, "rocksdb");
if (result.fail()) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << result.errorMessage();
LOG_TOPIC(ERR, arangodb::Logger::RESTORE) << result.errorMessage();
_exitCode = EXIT_FAILURE;
return;
}
@ -911,16 +910,16 @@ void RestoreFeature::start() {
result = ::processInputDirectory(*httpClient, _clientTaskQueue, *this,
_options, *_directory, _stats);
} catch (std::exception const& ex) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "caught exception " << ex.what();
LOG_TOPIC(ERR, arangodb::Logger::RESTORE) << "caught exception " << ex.what();
result = {TRI_ERROR_INTERNAL};
} catch (...) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
LOG_TOPIC(ERR, arangodb::Logger::RESTORE)
<< "Error: caught unknown exception";
result = {TRI_ERROR_INTERNAL};
}
if (result.fail()) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << result.errorMessage();
LOG_TOPIC(ERR, arangodb::Logger::RESTORE) << result.errorMessage();
_exitCode = EXIT_FAILURE;
}

View File

@ -80,7 +80,7 @@ ClientManager::~ClientManager() {}
Result ClientManager::getConnectedClient(
std::unique_ptr<httpclient::SimpleHttpClient>& httpClient, bool force,
bool verbose) {
bool logServerVersion, bool logDatabaseNotFound) {
ClientFeature* client =
application_features::ApplicationServer::getFeature<ClientFeature>(
"Client");
@ -104,16 +104,20 @@ Result ClientManager::getConnectedClient(
int errorCode;
std::string const versionString = httpClient->getServerVersion(&errorCode);
if (TRI_ERROR_NO_ERROR != errorCode) {
LOG_TOPIC(ERR, _topic) << "Could not connect to endpoint '"
<< client->endpoint() << "', database: '" << dbName
<< "', username: '" << client->username() << "'";
LOG_TOPIC(FATAL, _topic)
<< "Error message: '" << httpClient->getErrorMessage() << "'";
if (TRI_ERROR_ARANGO_DATABASE_NOT_FOUND != errorCode || logDatabaseNotFound) {
// arangorestore does not log "database not found" errors in case
// it tries to create the database...
LOG_TOPIC(ERR, _topic) << "Could not connect to endpoint '"
<< client->endpoint() << "', database: '" << dbName
<< "', username: '" << client->username() << "'";
LOG_TOPIC(ERR, _topic)
<< "Error message: '" << httpClient->getErrorMessage() << "'";
}
return {errorCode};
}
if (verbose) {
if (logServerVersion) {
// successfully connected
LOG_TOPIC(INFO, _topic) << "Server version: " << versionString;
}
@ -135,10 +139,10 @@ Result ClientManager::getConnectedClient(
}
std::unique_ptr<httpclient::SimpleHttpClient> ClientManager::getConnectedClient(
bool force, bool verbose) {
bool force, bool logServerVersion, bool logDatabaseNotFound) {
std::unique_ptr<httpclient::SimpleHttpClient> httpClient;
Result result = getConnectedClient(httpClient, force, verbose);
Result result = getConnectedClient(httpClient, force, logServerVersion, logDatabaseNotFound);
if (result.fail() && !(force && result.is(TRI_ERROR_INCOMPATIBLE_VERSION))) {
FATAL_ERROR_EXIT();
}

View File

@ -58,12 +58,13 @@ class ClientManager {
* @param httpclient Output pointer will be set on success
* @param force If true, an incompatible version will not result in an
* error result
* @param verbose If true, output the server version to logs
* @param logServerVersion If true, output the server version to logs
* @param logDatabaseNotFound If true, log errors when database was not found
* @return Status code and possible error message
*/
Result getConnectedClient(std::unique_ptr<httpclient::SimpleHttpClient>&
httpClient, bool force = false,
bool verbose = false);
httpClient, bool force, bool logServerVersion,
bool logDatabaseNotFound);
/**
* @brief Initializes a client, connects to server, and verifies version
@ -74,11 +75,12 @@ class ClientManager {
*
* @param force If true, an incompatible version will not result in a fatal
* error exit condition
* @param verbose If true, output the server version to logs
* @param logServerVersion If true, output the server version to logs
* @param logDatabaseNotFound If true, log errors when database was not found
* @return A connected `SimpleHttpClient`
*/
std::unique_ptr<httpclient::SimpleHttpClient> getConnectedClient(
bool force = false, bool verbose = false);
bool force, bool logServerVersion, bool logDatabaseNotFound);
/**
* @brief Conditionally prefixes a relative URI with database-specific path

View File

@ -216,7 +216,7 @@ inline bool ClientTaskQueue<JobData>::spawnWorkers(
try {
MUTEX_LOCKER(lock, _workersLock);
for (; spawned < numWorkers; spawned++) {
auto client = manager.getConnectedClient();
auto client = manager.getConnectedClient(false, false, true);
auto worker = std::make_unique<Worker>(*this, std::move(client));
_workers.emplace_back(std::move(worker));
_workers.back()->start();