audio_trans/orm_lib/inc/drogon/orm/Exception.h

553 lines
15 KiB
C
Raw Normal View History

2025-04-07 11:31:21 +08:00
/** Definition of Drogon Db exception classes.
*
* Copyright (c) 2003-2018, Jeroen T. Vermeulen.
*
* See COPYING for copyright license. If you did not receive a file called
* COPYING with this source code, please notify the distributor of this mistake,
* or contact the author.
*/
// taken from libpqxx and modified
/**
*
* @file Exception.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* Drogon
*
*/
#pragma once
#include <drogon/exports.h>
#include <functional>
#include <stdexcept>
#include <string>
namespace drogon
{
namespace orm
{
/// Mixin base class to identify drogon-db-specific exception types
/**
* If you wish to catch all exception types specific to drogon db for some
* reason,
* catch this type. All of drogon db's exception classes are derived from it
* through multiple-inheritance (they also fit into the standard library's
* exception hierarchy in more fitting places).
*
* This class is not derived from std::exception, since that could easily lead
* to exception classes with multiple std::exception base-class objects. As
* Bart Samwel points out, "catch" is subject to some nasty fineprint in such
* cases.
*/
class DROGON_EXPORT DrogonDbException
{
public:
/// Support run-time polymorphism, and keep this class abstract
virtual ~DrogonDbException() noexcept
{
}
/// Return std::exception base-class object
/**
* Use this to get at the exception's what() function, or to downcast to a
* more specific type using dynamic_cast.
*
* Casting directly from DrogonDbException to a specific exception type is
* not likely to work since DrogonDbException is not (and could not safely
* be) derived from std::exception.
*
* For example, to test dynamically whether an exception is an SqlError:
*
* @code
* try
* {
* // ...
* }
* catch (const drogon::orm::DrogonDbException &e)
* {
* std::cerr << e.base().what() << std::endl;
* const drogon::orm::SqlError *s=dynamic_cast<const
* drogon::orm::SqlError*>(&e.base());
* if (s) std::cerr << "Query was: " << s->query() << std::endl;
* }
* @endcode
*/
virtual const std::exception &base() const noexcept
{
static std::exception except;
return except;
} //[t00]
};
/// Run-time Failure encountered by drogon orm lib, similar to
/// std::runtime_error
class Failure : public DrogonDbException, public std::runtime_error
{
const std::exception &base() const noexcept override
{
return *this;
}
public:
DROGON_EXPORT explicit Failure(const std::string &);
};
/// Exception class for lost or failed backend connection.
/**
* @warning When this happens on Unix-like systems, you may also get a SIGPIPE
* signal. That signal aborts the program by default, so if you wish to be able
* to continue after a connection breaks, be sure to disarm this signal.
*
* If you're working on a Unix-like system, see the manual page for
* @c signal (2) on how to deal with SIGPIPE. The easiest way to make this
* signal harmless is to make your program ignore it:
*
* @code
* #include <signal.h>
*
* int main()
* {
* signal(SIGPIPE, SIG_IGN);
* // ...
* @endcode
*/
class BrokenConnection : public Failure
{
public:
DROGON_EXPORT BrokenConnection();
DROGON_EXPORT explicit BrokenConnection(const std::string &);
};
/// Exception class for failed queries.
/** Carries, in addition to a regular error message, a copy of the failed query
* and (if available) the SQLSTATE value accompanying the error.
*/
class SqlError : public Failure
{
/// Query string. Empty if unknown.
const std::string query_;
/// SQLSTATE string describing the error type, if known; or empty string.
const std::string sqlState_;
public:
DROGON_EXPORT explicit SqlError(const std::string &msg = "",
const std::string &Q = "",
const char sqlstate[] = nullptr);
DROGON_EXPORT virtual ~SqlError() noexcept;
/// The query whose execution triggered the exception
DROGON_EXPORT const std::string &query() const noexcept;
DROGON_EXPORT const std::string &sqlState() const noexcept;
};
/// "Help, I don't know whether transaction was committed successfully!"
/** Exception that might be thrown in rare cases where the connection to the
* database is lost while finishing a database transaction, and there's no way
* of telling whether it was actually executed by the backend. In this case
* the database is left in an indeterminate (but consistent) state, and only
* manual inspection will tell which is the case.
*/
class InDoubtError : public Failure
{
public:
DROGON_EXPORT explicit InDoubtError(const std::string &);
};
/// The backend saw itself forced to roll back the ongoing transaction.
class TransactionRollback : public Failure
{
public:
DROGON_EXPORT explicit TransactionRollback(const std::string &);
};
/// Transaction failed to serialize. Please retry it.
/** Can only happen at transaction isolation levels REPEATABLE READ and
* SERIALIZABLE.
*
* The current transaction cannot be committed without violating the guarantees
* made by its isolation level. This is the effect of a conflict with another
* ongoing transaction. The transaction may still succeed if you try to
* perform it again.
*/
class SerializationFailure : public TransactionRollback
{
public:
DROGON_EXPORT explicit SerializationFailure(const std::string &);
};
/// We can't tell whether our last statement succeeded.
class StatementCompletionUnknown : public TransactionRollback
{
public:
DROGON_EXPORT explicit StatementCompletionUnknown(const std::string &);
};
/// The ongoing transaction has deadlocked. Retrying it may help.
class DeadlockDetected : public TransactionRollback
{
public:
DROGON_EXPORT explicit DeadlockDetected(const std::string &);
};
/// Internal error in internal library
class InternalError : public DrogonDbException, public std::logic_error
{
const std::exception &base() const noexcept override
{
return *this;
}
public:
DROGON_EXPORT explicit InternalError(const std::string &);
};
/// Timeout error in when executing the SQL statement.
class TimeoutError : public DrogonDbException, public std::logic_error
{
const std::exception &base() const noexcept override
{
return *this;
}
public:
DROGON_EXPORT explicit TimeoutError(const std::string &);
};
/// Error in usage of drogon orm library, similar to std::logic_error
class UsageError : public DrogonDbException, public std::logic_error
{
const std::exception &base() const noexcept override
{
return *this;
}
public:
DROGON_EXPORT explicit UsageError(const std::string &);
};
/// Invalid argument passed to drogon orm lib, similar to std::invalid_argument
class ArgumentError : public DrogonDbException, public std::invalid_argument
{
const std::exception &base() const noexcept override
{
return *this;
}
public:
DROGON_EXPORT explicit ArgumentError(const std::string &);
};
/// Value conversion failed, e.g. when converting "Hello" to int.
class ConversionError : public DrogonDbException, public std::domain_error
{
const std::exception &base() const noexcept override
{
return *this;
}
public:
DROGON_EXPORT explicit ConversionError(const std::string &);
};
/// Something is out of range, similar to std::out_of_range
class RangeError : public DrogonDbException, public std::out_of_range
{
const std::exception &base() const noexcept override
{
return *this;
}
public:
DROGON_EXPORT explicit RangeError(const std::string &);
};
/// Query returned an unexpected number of rows.
class UnexpectedRows : public RangeError
{
const std::exception &base() const noexcept override
{
return *this;
}
public:
explicit UnexpectedRows(const std::string &msg) : RangeError(msg)
{
}
};
/// Database feature not supported in current setup
class FeatureNotSupported : public SqlError
{
public:
explicit FeatureNotSupported(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SqlError(err, Q, sqlstate)
{
}
};
/// Error in data provided to SQL statement
class DataException : public SqlError
{
public:
explicit DataException(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SqlError(err, Q, sqlstate)
{
}
};
class IntegrityConstraintViolation : public SqlError
{
public:
explicit IntegrityConstraintViolation(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SqlError(err, Q, sqlstate)
{
}
};
class RestrictViolation : public IntegrityConstraintViolation
{
public:
explicit RestrictViolation(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: IntegrityConstraintViolation(err, Q, sqlstate)
{
}
};
class NotNullViolation : public IntegrityConstraintViolation
{
public:
explicit NotNullViolation(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: IntegrityConstraintViolation(err, Q, sqlstate)
{
}
};
class ForeignKeyViolation : public IntegrityConstraintViolation
{
public:
explicit ForeignKeyViolation(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: IntegrityConstraintViolation(err, Q, sqlstate)
{
}
};
class UniqueViolation : public IntegrityConstraintViolation
{
public:
explicit UniqueViolation(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: IntegrityConstraintViolation(err, Q, sqlstate)
{
}
};
class CheckViolation : public IntegrityConstraintViolation
{
public:
explicit CheckViolation(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: IntegrityConstraintViolation(err, Q, sqlstate)
{
}
};
class InvalidCursorState : public SqlError
{
public:
explicit InvalidCursorState(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SqlError(err, Q, sqlstate)
{
}
};
class InvalidSqlStatementName : public SqlError
{
public:
explicit InvalidSqlStatementName(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SqlError(err, Q, sqlstate)
{
}
};
class InvalidCursorName : public SqlError
{
public:
explicit InvalidCursorName(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SqlError(err, Q, sqlstate)
{
}
};
class SyntaxError : public SqlError
{
public:
/// Approximate position in string where error occurred, or -1 if unknown.
const int errorPosition_;
explicit SyntaxError(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr,
int pos = -1)
: SqlError(err, Q, sqlstate), errorPosition_(pos)
{
}
};
class UndefinedColumn : public SyntaxError
{
public:
explicit UndefinedColumn(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SyntaxError(err, Q, sqlstate)
{
}
};
class UndefinedFunction : public SyntaxError
{
public:
explicit UndefinedFunction(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SyntaxError(err, Q, sqlstate)
{
}
};
class UndefinedTable : public SyntaxError
{
public:
explicit UndefinedTable(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SyntaxError(err, Q, sqlstate)
{
}
};
class InsufficientPrivilege : public SqlError
{
public:
explicit InsufficientPrivilege(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SqlError(err, Q, sqlstate)
{
}
};
/// Resource shortage on the server
class InsufficientResources : public SqlError
{
public:
explicit InsufficientResources(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: SqlError(err, Q, sqlstate)
{
}
};
class DiskFull : public InsufficientResources
{
public:
explicit DiskFull(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: InsufficientResources(err, Q, sqlstate)
{
}
};
class OutOfMemory : public InsufficientResources
{
public:
explicit OutOfMemory(const std::string &err,
const std::string &Q = "",
const char sqlstate[] = nullptr)
: InsufficientResources(err, Q, sqlstate)
{
}
};
class TooManyConnections : public BrokenConnection
{
public:
explicit TooManyConnections(const std::string &err) : BrokenConnection(err)
{
}
};
// /// PL/pgSQL error
// /** Exceptions derived from this class are errors from PL/pgSQL procedures.
// */
// class PQXX_LIBEXPORT plpgsql_error : public sql_error
// {
// public:
// explicit plpgsql_error(
// const std::string &err,
// const std::string &Q = "",
// const char sqlstate[] = nullptr) : sql_error(err, Q, sqlstate) {}
// };
// /// Exception raised in PL/pgSQL procedure
// class PQXX_LIBEXPORT plpgsql_raise : public plpgsql_error
// {
// public:
// explicit plpgsql_raise(
// const std::string &err,
// const std::string &Q = "",
// const char sqlstate[] = nullptr) : plpgsql_error(err, Q, sqlstate) {}
// };
// class PQXX_LIBEXPORT plpgsql_no_data_found : public plpgsql_error
// {
// public:
// explicit plpgsql_no_data_found(
// const std::string &err,
// const std::string &Q = "",
// const char sqlstate[] = nullptr) : plpgsql_error(err, Q, sqlstate) {}
// };
// class PQXX_LIBEXPORT plpgsql_too_many_rows : public plpgsql_error
// {
// public:
// explicit plpgsql_too_many_rows(
// const std::string &err,
// const std::string &Q = "",
// const char sqlstate[] = nullptr) : plpgsql_error(err, Q, sqlstate) {}
// };
using DrogonDbExceptionCallback =
std::function<void(const DrogonDbException &)>;
} // namespace orm
} // namespace drogon