2017-04-19 21:52:20 +08:00
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @brief This file stores the common exceptions used across the project.
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <exception>
|
|
|
|
|
|
|
|
#include <fmt/format.h>
|
|
|
|
#include <fmt/ostream.h>
|
|
|
|
|
2017-06-13 21:43:00 +08:00
|
|
|
#include "utils/stacktrace.hpp"
|
2017-04-19 21:52:20 +08:00
|
|
|
|
|
|
|
namespace utils {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Base class for all regular exceptions.
|
|
|
|
*
|
|
|
|
* All custom exceptions should inherit from this class. It stores the message
|
|
|
|
* with which it was constructed. To retrieve the message, use
|
|
|
|
* @c BasicException::what method. In case you need to store a stack trace, you
|
|
|
|
* should use @c StacktraceException
|
|
|
|
*
|
|
|
|
* @sa StacktraceException
|
|
|
|
* @sa NotYetImplemented
|
|
|
|
*/
|
|
|
|
class BasicException : public std::exception {
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* @brief Constructor (C strings).
|
|
|
|
*
|
|
|
|
* @param message C-style string error message.
|
|
|
|
* The string contents are copied upon construction.
|
|
|
|
* Hence, responsibility for deleting the `char*` lies
|
|
|
|
* with the caller.
|
|
|
|
*/
|
|
|
|
explicit BasicException(const char *message) noexcept : msg_(message) {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Constructor (C++ STL strings).
|
|
|
|
*
|
|
|
|
* @param message The error message.
|
|
|
|
*/
|
2017-11-09 20:46:37 +08:00
|
|
|
explicit BasicException(const std::string &message) noexcept
|
|
|
|
: msg_(message) {}
|
2017-04-19 21:52:20 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Constructor with format string (C++ STL strings).
|
|
|
|
*
|
|
|
|
* @param format The error format message.
|
|
|
|
* @param args Arguments for format string.
|
|
|
|
*/
|
|
|
|
template <class... Args>
|
|
|
|
explicit BasicException(const std::string &format, Args &&... args) noexcept
|
|
|
|
: BasicException(fmt::format(format, std::forward<Args>(args)...)) {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Constructor with format string (C strings).
|
|
|
|
*
|
|
|
|
* @param format The error format message. The string contents are copied upon
|
|
|
|
* construction. Hence, the responsibility for deleting `char*` lies with the
|
|
|
|
* caller.
|
|
|
|
* @param args Arguments for format string.
|
|
|
|
*/
|
|
|
|
template <class... Args>
|
|
|
|
explicit BasicException(const char *format, Args &&... args) noexcept
|
2017-11-09 20:46:37 +08:00
|
|
|
: BasicException(
|
|
|
|
fmt::format(std::string(format), std::forward<Args>(args)...)) {}
|
2017-04-19 21:52:20 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Virtual destructor to allow for subclassing.
|
|
|
|
*/
|
|
|
|
virtual ~BasicException() {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Returns a pointer to the (constant) error description.
|
|
|
|
*
|
|
|
|
* @return A pointer to a `const char*`. The underlying memory
|
|
|
|
* is in possession of the @c BasicException object. Callers must
|
|
|
|
* not attempt to free the memory.
|
|
|
|
*/
|
|
|
|
const char *what() const noexcept override { return msg_.c_str(); }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/**
|
|
|
|
* @brief Error message.
|
|
|
|
*/
|
|
|
|
std::string msg_;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Base class for all exceptions which need to store the stack trace.
|
|
|
|
*
|
|
|
|
* When you need to store the stack trace from the place this exception is
|
|
|
|
* created, you should use this class. The error message can be obtained using
|
|
|
|
* @c StacktraceException::what method, while the stack trace itself can be
|
|
|
|
* obtained via @c StacktraceException::trace method. If the stack trace is not
|
|
|
|
* needed, you should use @c BasicException.
|
|
|
|
*
|
|
|
|
* @sa BasicException
|
|
|
|
* @sa NotYetImplemented
|
|
|
|
*/
|
|
|
|
class StacktraceException : public std::exception {
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* @brief Constructor (C strings).
|
|
|
|
*
|
|
|
|
* @param message C-style string error message.
|
|
|
|
* The string contents are copied upon construction.
|
|
|
|
* Hence, responsibility for deleting the `char*` lies
|
|
|
|
* with the caller.
|
|
|
|
*/
|
|
|
|
explicit StacktraceException(const char *message) noexcept
|
2017-11-09 20:46:37 +08:00
|
|
|
: message_(message), stacktrace_(Stacktrace().dump()) {}
|
2017-04-19 21:52:20 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Constructor (C++ STL strings).
|
|
|
|
*
|
|
|
|
* @param message The error message.
|
|
|
|
*/
|
|
|
|
explicit StacktraceException(const std::string &message) noexcept
|
2017-11-09 20:46:37 +08:00
|
|
|
: message_(message), stacktrace_(Stacktrace().dump()) {}
|
2017-04-19 21:52:20 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Constructor with format string (C++ STL strings).
|
|
|
|
*
|
|
|
|
* @param format The error format message.
|
|
|
|
* @param args Arguments for format string.
|
|
|
|
*/
|
|
|
|
template <class... Args>
|
|
|
|
explicit StacktraceException(const std::string &format,
|
|
|
|
Args &&... args) noexcept
|
|
|
|
: StacktraceException(fmt::format(format, std::forward<Args>(args)...)) {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Constructor with format string (C strings).
|
|
|
|
*
|
|
|
|
* @param format The error format message. The string contents are copied upon
|
|
|
|
* construction. Hence, the responsibility for deleting `char*` lies with the
|
|
|
|
* caller.
|
|
|
|
* @param args Arguments for format string.
|
|
|
|
*/
|
|
|
|
template <class... Args>
|
|
|
|
explicit StacktraceException(const char *format, Args &&... args) noexcept
|
2017-11-09 20:46:37 +08:00
|
|
|
: StacktraceException(
|
|
|
|
fmt::format(std::string(format), std::forward<Args>(args)...)) {}
|
2017-04-19 21:52:20 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Virtual destructor to allow for subclassing.
|
|
|
|
*/
|
|
|
|
virtual ~StacktraceException() {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Returns a pointer to the (constant) error description.
|
|
|
|
*
|
|
|
|
* @return A pointer to a `const char*`. The underlying memory
|
|
|
|
* is in possession of the @c StacktraceException object. Callers must
|
|
|
|
* not attempt to free the memory.
|
|
|
|
*/
|
|
|
|
const char *what() const noexcept override { return message_.c_str(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Returns a pointer to the (constant) stack trace message.
|
|
|
|
*
|
|
|
|
* @return A pointer to a `const char*`. The underlying memory
|
|
|
|
* is in possession of the @c StacktraceException object. Callers must
|
|
|
|
* not attempt to free the memory.
|
|
|
|
*/
|
|
|
|
const char *trace() const noexcept { return stacktrace_.c_str(); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::string message_;
|
|
|
|
std::string stacktrace_;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Raise this exception for functionality which is yet to be implemented.
|
|
|
|
*/
|
2017-07-18 17:15:08 +08:00
|
|
|
class NotYetImplemented final : public BasicException {
|
2017-04-19 21:52:20 +08:00
|
|
|
public:
|
2017-07-18 17:15:08 +08:00
|
|
|
explicit NotYetImplemented(const std::string &what) noexcept
|
|
|
|
: BasicException("Not yet implemented: " + what) {}
|
2017-04-19 21:52:20 +08:00
|
|
|
|
2017-07-18 17:15:08 +08:00
|
|
|
template <class... Args>
|
|
|
|
explicit NotYetImplemented(const std::string &format,
|
|
|
|
Args &&... args) noexcept
|
|
|
|
: NotYetImplemented(fmt::format(format, std::forward<Args>(args)...)) {}
|
2017-04-19 21:52:20 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace utils
|