Skip to content

Error: Simplify error::Error #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 9 additions & 28 deletions error/include/error/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,40 @@
#include <fmt/core.h>

#include <exception>
#include <memory>
#include <string>
#include <utility>

namespace error {

/**
* @brief A class that represents error information.
* @brief Represents error information.
*/
class Error : public std::exception {
private:
struct Error : public std::exception {
std::string message; /**< The error message. */

public:
/**
* @brief Constructs a new error with the given format for the message.
* @tparam T Variadic template parameter pack for format arguments.
* @param fmt A format string for the message.
* @param args Format arguments.
* @brief Constructs a new error object with the given message.
* @param msg An error message.
*/
template <typename... T>
Error(fmt::format_string<T...> fmt, T&&... args)
: message(fmt::format(fmt, std::forward<T>(args)...)) {}
Error(const std::string& msg);

/**
* @brief Returns the explanatory string.
* @return Pointer to a null-terminated string with explanatory information.
*/
const char* what() const noexcept override;

/**
* @brief Checks if the error message matches the given string.
* @param str A string to be matched.
* @return True if it matches, false otherwise.
*/
bool matches(const std::string& str) const noexcept;
};

/**
* @brief Alias for a shared pointer to the `Error` class.
*/
using ErrorPtr = std::shared_ptr<Error>;

/**
* @brief Creates a new error pointer with the given format for the message.
* @brief Creates a new error object with a formatted message.
* @tparam T Variadic template parameter pack for format arguments.
* @param fmt A format string for the message.
* @param args Format arguments.
* @return Shared pointer to a new error.
* @return A new error object.
*/
template <typename... T>
ErrorPtr make(fmt::format_string<T...> fmt, T&&... args) {
return std::make_shared<Error>(fmt, std::forward<T>(args)...);
Error format(fmt::format_string<T...> fmt, T&&... args) {
return Error(fmt::format(fmt, std::forward<T>(args)...));
}

} // namespace error
6 changes: 2 additions & 4 deletions error/src/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

namespace error {

const char* Error::what() const noexcept { return message.c_str(); }
Error::Error(const std::string& msg) : message(msg) {}

bool Error::matches(const std::string& str) const noexcept {
return message == str;
}
const char* Error::what() const noexcept { return message.c_str(); }

} // namespace error
31 changes: 6 additions & 25 deletions error/test/error_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,21 @@
#include <string>

TEST_CASE("Error Construction") {
SECTION("With one argument") {
const error::Error err("unknown error");
REQUIRE(err.matches("unknown error"));
}

SECTION("With one or more arguments") {
const error::Error err("HTTP error {}", 404);
REQUIRE(err.matches("HTTP error 404"));
}
const error::Error err("unknown error");
REQUIRE(err.message == "unknown error");
}

TEST_CASE("Error Pointer Construction") {
SECTION("With one argument") {
const error::ErrorPtr err = error::make("unknown error");
REQUIRE(err->matches("unknown error"));
}

SECTION("With one or more arguments") {
const error::ErrorPtr err = error::make("HTTP error {}", 404);
REQUIRE(err->matches("HTTP error 404"));
}
TEST_CASE("Error Construction With Formatting") {
const error::Error err = error::format("HTTP error {}", 404);
REQUIRE(err.message == "HTTP error 404");
}

TEST_CASE("Error Throwing and Catching") {
SECTION("Catch as error::Error") {
try {
throw error::Error("unknown error");
} catch (const error::Error& err) {
REQUIRE(err.matches("unknown error"));
REQUIRE(err.message == "unknown error");
} catch (...) {
FAIL("Expected to be caught as error::Error");
}
Expand All @@ -47,8 +33,3 @@ TEST_CASE("Error Throwing and Catching") {
}
}
}

TEST_CASE("Error Message Matching") {
const error::Error err("unknown error");
REQUIRE(err.matches("unknown error"));
}