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 <glog/logging.h>
|
||||||
|
|
||||||
#include "communication/bolt/v1/codes.hpp"
|
#include "communication/bolt/v1/codes.hpp"
|
||||||
|
#include "communication/bolt/v1/exceptions.hpp"
|
||||||
#include "communication/bolt/v1/state.hpp"
|
#include "communication/bolt/v1/state.hpp"
|
||||||
#include "communication/bolt/v1/value.hpp"
|
#include "communication/bolt/v1/value.hpp"
|
||||||
#include "utils/exceptions.hpp"
|
|
||||||
|
|
||||||
namespace communication::bolt {
|
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
|
// TODO (mferencevic): revise these error messages
|
||||||
inline std::pair<std::string, std::string> ExceptionToErrorMessage(
|
inline std::pair<std::string, std::string> ExceptionToErrorMessage(
|
||||||
const std::exception &e) {
|
const std::exception &e) {
|
||||||
|
if (auto *verbose = dynamic_cast<const VerboseError *>(&e)) {
|
||||||
|
return {verbose->code(), verbose->what()};
|
||||||
|
}
|
||||||
if (dynamic_cast<const ClientError *>(&e)) {
|
if (dynamic_cast<const ClientError *>(&e)) {
|
||||||
// Clients expect 4 strings separated by dots. First being database name
|
// Clients expect 4 strings separated by dots. First being database name
|
||||||
// (for example: Neo, Memgraph...), second being either ClientError,
|
// (for example: Neo, Memgraph...), second being either ClientError,
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "audit/log.hpp"
|
#include "audit/log.hpp"
|
||||||
#include "auth/auth.hpp"
|
#include "auth/auth.hpp"
|
||||||
|
#include "communication/bolt/v1/exceptions.hpp"
|
||||||
#include "communication/bolt/v1/session.hpp"
|
#include "communication/bolt/v1/session.hpp"
|
||||||
#include "communication/init.hpp"
|
#include "communication/init.hpp"
|
||||||
#include "communication/session.hpp"
|
#include "communication/session.hpp"
|
||||||
|
@ -2,15 +2,19 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "utils/exceptions.hpp"
|
#include "communication/bolt/v1/exceptions.hpp"
|
||||||
|
|
||||||
namespace raft {
|
namespace raft {
|
||||||
|
|
||||||
/// Base exception class used for all exceptions that can occur within the
|
/// Base exception class used for all exceptions that can occur within the
|
||||||
/// Raft protocol.
|
/// Raft protocol.
|
||||||
class RaftException : public utils::BasicException {
|
class RaftException : public communication::bolt::VerboseError {
|
||||||
public:
|
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
|
/// This exception should be thrown when attempting to transition between
|
||||||
|
Loading…
Reference in New Issue
Block a user