Add bolt verbose error
Reviewers: msantl Reviewed By: msantl Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1948
This commit is contained in:
parent
c269e2f468
commit
4029026c3b
78
src/communication/bolt/v1/exceptions.hpp
Normal file
78
src/communication/bolt/v1/exceptions.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
/// @file
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
|
||||
/**
|
||||
* Used to indicate something is wrong with the client but the transaction is
|
||||
* kept open for a potential retry.
|
||||
*
|
||||
* The most common use case for throwing this error is if something is wrong
|
||||
* with the query. Perhaps a simple syntax error that can be fixed and query
|
||||
* retried.
|
||||
*/
|
||||
class ClientError : public utils::BasicException {
|
||||
public:
|
||||
using utils::BasicException::BasicException;
|
||||
};
|
||||
|
||||
/**
|
||||
* All exceptions that are sent to the client consist of two parts. The first
|
||||
* part is `code` it specifies the type of exception that was raised. The second
|
||||
* part is `message` which is a pretty error message that can be displayed to a
|
||||
* human.
|
||||
*
|
||||
* The first part is more interesting for machine processing. It should have the
|
||||
* following format: `Memgraph.[Classification].[Category].[Title]` It is
|
||||
* defined here: https://neo4j.com/docs/status-codes/current/
|
||||
*
|
||||
* The first part of the `code` is always Memgraph, it indicates the database.
|
||||
* The second part is `classification`. The `classification` part is specified
|
||||
* by Neo to always be one of "ClientError", "ClientNotification",
|
||||
* "TransientError" or "DatabaseError". We won't use "ClientNotification".
|
||||
*
|
||||
* The `category` and `title` parts can be freely specified.
|
||||
*/
|
||||
class VerboseError : public utils::BasicException {
|
||||
public:
|
||||
enum class Classification {
|
||||
// Client and Database errors mean that the client shouldn't retry the
|
||||
// query.
|
||||
CLIENT_ERROR,
|
||||
DATABASE_ERROR,
|
||||
// Transient error means that the client should retry the query.
|
||||
TRANSIENT_ERROR,
|
||||
};
|
||||
|
||||
template <class... Args>
|
||||
VerboseError(Classification classification, const std::string &category,
|
||||
const std::string &title, const std::string &format,
|
||||
Args &&... args)
|
||||
: BasicException(format, std::forward<Args>(args)...),
|
||||
code_(fmt::format("Memgraph.{}.{}.{}",
|
||||
ClassificationToString(classification), category,
|
||||
title)) {}
|
||||
|
||||
const std::string &code() const noexcept { return code_; }
|
||||
|
||||
private:
|
||||
std::string ClassificationToString(Classification classification) {
|
||||
switch (classification) {
|
||||
case Classification::CLIENT_ERROR:
|
||||
return "ClientError";
|
||||
case Classification::DATABASE_ERROR:
|
||||
return "DatabaseError";
|
||||
case Classification::TRANSIENT_ERROR:
|
||||
return "TransientError";
|
||||
}
|
||||
}
|
||||
|
||||
std::string code_;
|
||||
};
|
||||
|
||||
} // namespace communication::bolt
|
@ -7,28 +7,18 @@
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include "communication/bolt/v1/codes.hpp"
|
||||
#include "communication/bolt/v1/exceptions.hpp"
|
||||
#include "communication/bolt/v1/state.hpp"
|
||||
#include "communication/bolt/v1/value.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
|
||||
/**
|
||||
* Used to indicate something is wrong with the client but the transaction is
|
||||
* kept open for a potential retry.
|
||||
*
|
||||
* The most common use case for throwing this error is if something is wrong
|
||||
* with the query. Perhaps a simple syntax error that can be fixed and query
|
||||
* retried.
|
||||
*/
|
||||
class ClientError : public utils::BasicException {
|
||||
public:
|
||||
using utils::BasicException::BasicException;
|
||||
};
|
||||
|
||||
// TODO (mferencevic): revise these error messages
|
||||
inline std::pair<std::string, std::string> ExceptionToErrorMessage(
|
||||
const std::exception &e) {
|
||||
if (auto *verbose = dynamic_cast<const VerboseError *>(&e)) {
|
||||
return {verbose->code(), verbose->what()};
|
||||
}
|
||||
if (dynamic_cast<const ClientError *>(&e)) {
|
||||
// Clients expect 4 strings separated by dots. First being database name
|
||||
// (for example: Neo, Memgraph...), second being either ClientError,
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "audit/log.hpp"
|
||||
#include "auth/auth.hpp"
|
||||
#include "communication/bolt/v1/exceptions.hpp"
|
||||
#include "communication/bolt/v1/session.hpp"
|
||||
#include "communication/init.hpp"
|
||||
#include "communication/session.hpp"
|
||||
|
@ -2,15 +2,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "communication/bolt/v1/exceptions.hpp"
|
||||
|
||||
namespace raft {
|
||||
|
||||
/// Base exception class used for all exceptions that can occur within the
|
||||
/// Raft protocol.
|
||||
class RaftException : public utils::BasicException {
|
||||
class RaftException : public communication::bolt::VerboseError {
|
||||
public:
|
||||
using utils::BasicException::BasicException;
|
||||
template <class... Args>
|
||||
RaftException(const std::string &format, Args &&... args)
|
||||
: communication::bolt::VerboseError(
|
||||
communication::bolt::VerboseError::Classification::DATABASE_ERROR,
|
||||
"Raft", "Error", format, std::forward<Args>(args)...) {}
|
||||
};
|
||||
|
||||
/// This exception should be thrown when attempting to transition between
|
||||
|
Loading…
Reference in New Issue
Block a user