Skip to content
Snippets Groups Projects

Better Error Handling and Logging

Merged Timm Fitschen requested to merge dev into main
1 file
+ 5
0
Compare changes
  • Side-by-side
  • Inline
+ 170
0
/*
* This file is a part of the CaosDB Project.
*
* Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
* Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifndef CAOSDB_TRANSACTION_STATUS_H
#define CAOSDB_TRANSACTION_STATUS_H
/**
* TransactionStatus indicates the current status of a transaction and, when it
* has already terminated, whether the transaction has been successful or not.
*
* A status code of 0 denotes a generic success state, positive values indicate
* errors, and negative values indicate other states, such as different stages
* of a transaction in process.
*/
#include "caosdb/status_code.h"
#include "caosdb/exceptions.h"
#include <memory> // for shared_ptr, unique_ptr
#include <string> // for string
namespace caosdb::transaction {
using caosdb::StatusCode;
using caosdb::exceptions::AuthenticationError;
using caosdb::exceptions::ConnectionError;
using caosdb::exceptions::Exception;
using caosdb::exceptions::TransactionError;
/**
* Status of a Request or Transaction.
*/
class TransactionStatus {
public:
// REFACTORING NEEDED: When you touch this code again consider writing a
// macro, because this is a lot of redundant code here...
inline static auto INITIAL() -> const TransactionStatus & {
static const TransactionStatus initial(
StatusCode::INITIAL, caosdb::get_status_description(StatusCode::INITIAL));
return initial;
}
inline static auto EXECUTING() -> const TransactionStatus & {
static const TransactionStatus executing(
StatusCode::EXECUTING,
caosdb::get_status_description(StatusCode::EXECUTING));
return executing;
}
inline static auto SUCCESS() -> const TransactionStatus & {
static const TransactionStatus success(
StatusCode::SUCCESS, caosdb::get_status_description(StatusCode::SUCCESS));
return success;
}
inline static auto RPC_ERROR(const std::string &details)
-> const TransactionStatus {
// We use the GENERIC_RPC_ERROR here because we might want to add further
// RPC_ERROR states with different error codes (which stem from GRPC) here
// in the future.
return TransactionStatus(
StatusCode::GENERIC_RPC_ERROR,
caosdb::get_status_description(StatusCode::GENERIC_RPC_ERROR) +
" Original error: " + details);
}
inline static auto CONNECTION_ERROR() -> const TransactionStatus & {
static const TransactionStatus connection_error(
StatusCode::CONNECTION_ERROR,
caosdb::get_status_description(StatusCode::CONNECTION_ERROR));
return connection_error;
}
inline static auto AUTHENTICATION_ERROR(const std::string &details)
-> const TransactionStatus {
return TransactionStatus(
StatusCode::AUTHENTICATION_ERROR,
caosdb::get_status_description(StatusCode::AUTHENTICATION_ERROR) +
" Original error: " + details);
}
inline static auto AUTHENTICATION_ERROR() -> const TransactionStatus & {
static const TransactionStatus authentication_error(
StatusCode::AUTHENTICATION_ERROR,
caosdb::get_status_description(StatusCode::AUTHENTICATION_ERROR));
return authentication_error;
}
inline static auto TRANSACTION_ERROR() -> const TransactionStatus & {
static const TransactionStatus transaction_error(
StatusCode::GENERIC_TRANSACTION_ERROR,
caosdb::get_status_description(StatusCode::GENERIC_TRANSACTION_ERROR));
return transaction_error;
}
inline static auto TRANSACTION_ERROR(const std::string &details)
-> const TransactionStatus {
return TransactionStatus(
StatusCode::GENERIC_TRANSACTION_ERROR,
caosdb::get_status_description(StatusCode::GENERIC_TRANSACTION_ERROR) +
" Original error: " + details);
}
inline auto ThrowExceptionIfError() const -> void {
if (!IsError()) {
return;
}
switch (this->code) {
case StatusCode::CONNECTION_ERROR:
throw ConnectionError(this->description);
case StatusCode::AUTHENTICATION_ERROR:
throw AuthenticationError(this->description);
case StatusCode::GENERIC_TRANSACTION_ERROR:
throw TransactionError(this->description);
default:
throw Exception(StatusCode::GENERIC_ERROR, this->description);
}
}
/**
* Return true if this TransactionStatus represents a terminated state.
*/
inline auto IsTerminated() const -> bool { return this->code >= 0; };
/**
* Return true if this TransactionStatus represents an erroneous state.
*/
inline auto IsError() const -> bool { return this->code > 0; };
/**
* Return a description of the erroneous state.
*
* No description yields an empty string.
*/
inline auto GetDescription() const -> const std::string & {
return this->description;
}
/**
* Return the status code of the state.
*/
inline auto GetCode() const -> StatusCode { return this->code; }
private:
/**
* The code is an identifier of errors.
*/
StatusCode code;
/**
* Description of the error
*/
std::string description;
TransactionStatus(StatusCode code, const std::string &description)
: code(code), description(description){};
};
} // namespace caosdb::transaction
#endif
Loading