Mercurial > malikania
changeset 180:23ee2b6091e8
Server: add custom error code
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 21 Aug 2018 10:55:13 +0200 |
parents | ffe8ac5c35c0 |
children | fbfc2555bda5 |
files | libcommon/CMakeLists.txt libcommon/malikania/error/auth_error.cpp libcommon/malikania/error/auth_error.hpp libcommon/malikania/error/error.hpp libserver/malikania/server/client.cpp libserver/malikania/server/client.hpp libserver/malikania/server/net/auth_handler.cpp |
diffstat | 7 files changed, 236 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/libcommon/CMakeLists.txt Mon Oct 08 09:51:12 2018 +0200 +++ b/libcommon/CMakeLists.txt Tue Aug 21 10:55:13 2018 +0200 @@ -23,6 +23,8 @@ set( HEADERS + ${libmlk-common_SOURCE_DIR}/malikania/error/error.hpp + ${libmlk-common_SOURCE_DIR}/malikania/error/auth_error.hpp ${libmlk-common_SOURCE_DIR}/malikania/game.hpp ${libmlk-common_SOURCE_DIR}/malikania/loader.hpp ${libmlk-common_SOURCE_DIR}/malikania/locator.hpp @@ -34,6 +36,7 @@ set( SOURCES + ${libmlk-common_SOURCE_DIR}/malikania/error/auth_error.cpp ${libmlk-common_SOURCE_DIR}/malikania/loader.cpp ${libmlk-common_SOURCE_DIR}/malikania/locator.cpp ${libmlk-common_SOURCE_DIR}/malikania/unicode.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/malikania/error/auth_error.cpp Tue Aug 21 10:55:13 2018 +0200 @@ -0,0 +1,40 @@ +/* + * auth_error.hpp -- auth command error + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "auth_error.hpp" + +namespace mlk { + +auto auth_error::error_category() -> std::string +{ + return "auth"; +} + +auto auth_error::error_message(error code) -> std::string +{ + switch (code) { + case invalid_credentials: + return "invalid credentials"; + case already_connected: + return "already connected"; + default: + return "no error"; + } +} + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/malikania/error/auth_error.hpp Tue Aug 21 10:55:13 2018 +0200 @@ -0,0 +1,73 @@ +/* + * auth_error.hpp -- auth command error + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_AUTH_ERROR_HPP +#define MALIKANIA_AUTH_ERROR_HPP + +/** + * \file auth_error.hpp + * \brief Auth command error. + */ + +#include "error.hpp" + +namespace mlk { + +/** + * \brief Auth command error. + */ +struct auth_error { + /** + * \brief Error description + */ + enum error { + /** + * \brief No error. + */ + no_error = 0, + + /** + * \brief Invalid password or login. + */ + invalid_credentials, + + /** + * \brief User is already connected. + */ + already_connected + }; + + static auto error_category() -> std::string; + + /** + * Convert the code to a human message. + * + * \param code the code + */ + static auto error_message(error code) -> std::string; +}; + +} // !mlk + +MALIKANIA_ERROR_CODE( + mlk::auth_error::error, + mlk::auth_error::error_category, + mlk::auth_error::error_message +) + +#endif // !MALIKANIA_AUTH_ERROR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/malikania/error/error.hpp Tue Aug 21 10:55:13 2018 +0200 @@ -0,0 +1,99 @@ +/* + * error.hpp -- error code creation + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_ERROR_HPP +#define MALIKANIA_ERROR_HPP + +/** + * \file error.hpp + * \brief Error code creation. + */ + +#include <string> +#include <system_error> +#include <type_traits> + +/** + * Generate a custom std::error_code with the given type. The macro must be + * called outside mlk namespace. + * + * See the following example. + * + * ```cpp + * namespace mlk { + * + * class foo { + * public: + * enum class error { + * no_error = 0, + * error_kind_foo, + * error_kind_bar + * }; + * + * static auto error_category() -> std::string + * { + * return "sometext"; + * } + * + * static auto error_message(error code) -> std::string + * { + * // convert code to a string. + * } + * }; + * + * } // !mlk + * + * MALIKANIA_ERROR_CODE( + * my_error::error, + * my_error::error_category, + * my_error::error_message + * ) + * ``` + */ +#define MALIKANIA_ERROR_CODE(Enum, Category, Message) \ +namespace std { \ + \ +template <> \ +struct is_error_code_enum<Enum> : public std::true_type { \ +}; \ + \ +} \ + \ +namespace mlk { \ + \ +inline auto make_error_code(Enum code) noexcept -> std::error_code \ +{ \ + static const class : public std::error_category { \ + public: \ + auto name() const noexcept -> const char* override \ + { \ + return Category().c_str(); \ + } \ + \ + auto message(int e) const -> std::string override \ + { \ + return Message(static_cast<Enum>(e)); \ + } \ + } category; \ + \ + return { static_cast<int>(code), category }; \ +} \ + \ +} + +#endif // !MALIKANIA_ERROR_HPP
--- a/libserver/malikania/server/client.cpp Mon Oct 08 09:51:12 2018 +0200 +++ b/libserver/malikania/server/client.cpp Tue Aug 21 10:55:13 2018 +0200 @@ -167,25 +167,18 @@ send(std::move(message)); } -void client::error(std::string cmd, nlohmann::json args) +void client::error(std::string cmd, std::error_code code) { - assert(args.is_object() || args.is_string()); - - if (args.is_string()) { - args = nlohmann::json::object({ - { "error", args.get<std::string>() } - }); - } - - args["command"] = std::move(cmd); - args["status"] = false; - - send(std::move(args)); + send({ + { "command", std::move(cmd) }, + { "status", code.value() }, + { "error", code.message() } + }); } -void client::fatal(std::string cmd, nlohmann::json args) +void client::fatal(std::string cmd, std::error_code code) { - error(std::move(cmd), std::move(args)); + error(std::move(cmd), std::move(code)); state_ = state::closing; }
--- a/libserver/malikania/server/client.hpp Mon Oct 08 09:51:12 2018 +0200 +++ b/libserver/malikania/server/client.hpp Tue Aug 21 10:55:13 2018 +0200 @@ -30,6 +30,7 @@ #include <optional> #include <sstream> #include <string> +#include <system_error> #include <boost/asio.hpp> #include <boost/asio/ssl.hpp> @@ -158,24 +159,24 @@ /** * Send a error command result. * - * \pre !cmd.empty() && !reason.empty() - * \pre args.is_object() || args.is_string() + * \pre !cmd.empty() + * \pre code * \param cmd the command name - * \param args the extra data (can be a string) + * \param code the error code */ - void error(std::string cmd, nlohmann::json args); + void error(std::string cmd, std::error_code code); /** * Send a fatal error result. * * The client state is changed to closing. * - * \pre !cmd.empty() && !reason.empty() - * \pre args.is_object() || args.is_string() + * \pre !cmd.empty() + * \pre code * \param cmd the command name - * \param args the extra data (can be a string) + * \param code the error code */ - void fatal(std::string cmd, nlohmann::json args); + void fatal(std::string cmd, std::error_code code); }; } // !mlk::server
--- a/libserver/malikania/server/net/auth_handler.cpp Mon Oct 08 09:51:12 2018 +0200 +++ b/libserver/malikania/server/net/auth_handler.cpp Tue Aug 21 10:55:13 2018 +0200 @@ -18,6 +18,8 @@ #include <util.hpp> +#include <malikania/error/auth_error.hpp> + #include "db/account.hpp" #include "auth_handler.hpp" @@ -51,9 +53,9 @@ ); if (!ac) - clt.error("auth", "invalid credentials"); + clt.fatal("auth", auth_error::invalid_credentials); else if (is_connected(server, *ac)) - clt.error("auth", "already connected"); + clt.fatal("auth", auth_error::already_connected); else { clt.set_account(std::move(*ac)); clt.set_state(client::state::ready);