Commit 6dbaee56 authored by Dominik Charousset's avatar Dominik Charousset

Use type IDs for error code enums

parent f0041b0e
...@@ -96,14 +96,14 @@ void caf_main(actor_system& sys) { ...@@ -96,14 +96,14 @@ void caf_main(actor_system& sys) {
binary_serializer bs{sys, buf}; binary_serializer bs{sys, buf};
auto e = bs(f1); auto e = bs(f1);
if (e) { if (e) {
std::cerr << "*** unable to serialize foo2: " << sys.render(e) << std::endl; std::cerr << "*** unable to serialize foo2: " << to_string(e) << '\n';
return; return;
} }
// read f2 back from buffer // read f2 back from buffer
binary_deserializer bd{sys, buf}; binary_deserializer bd{sys, buf};
e = bd(f2); e = bd(f2);
if (e) { if (e) {
std::cerr << "*** unable to serialize foo2: " << sys.render(e) << std::endl; std::cerr << "*** unable to serialize foo2: " << to_string(e) << '\n';
return; return;
} }
// must be equal // must be equal
......
...@@ -242,7 +242,8 @@ public: ...@@ -242,7 +242,8 @@ public:
actor_registry& registry(); actor_registry& registry();
/// Returns a string representation for `err`. /// Returns a string representation for `err`.
std::string render(const error& x) const; [[deprecated("please use to_string() on the error")]] std::string
render(const error& x) const;
/// Returns the system-wide group manager. /// Returns the system-wide group manager.
group_manager& groups(); group_manager& groups();
......
...@@ -67,10 +67,6 @@ public: ...@@ -67,10 +67,6 @@ public:
using portable_name_map = hash_map<std::type_index, std::string>; using portable_name_map = hash_map<std::type_index, std::string>;
using error_renderer = std::function<std::string(uint8_t, const message&)>;
using error_renderer_map = hash_map<uint8_t, error_renderer>;
using group_module_factory = std::function<group_module*()>; using group_module_factory = std::function<group_module*()>;
using group_module_factory_vector = std::vector<group_module_factory>; using group_module_factory_vector = std::vector<group_module_factory>;
...@@ -154,29 +150,6 @@ public: ...@@ -154,29 +150,6 @@ public:
return add_actor_factory(std::move(name), make_actor_factory(std::move(f))); return add_actor_factory(std::move(name), make_actor_factory(std::move(f)));
} }
/// Enables the actor system to convert errors of this error category
/// to human-readable strings via `renderer`.
actor_system_config& add_error_category(uint8_t category, error_renderer f);
/// Enables the actor system to convert errors of this error category
/// to human-readable strings via `to_string(T)`.
template <class T>
actor_system_config&
add_error_category(uint8_t category, string_view category_name) {
auto f = [=](uint8_t val, const std::string& ctx) -> std::string {
std::string result{category_name.begin(), category_name.end()};
result += ": ";
result += to_string(static_cast<T>(val));
if (!ctx.empty()) {
result += " (";
result += ctx;
result += ")";
}
return result;
};
return add_error_category(category, error_renderer{f});
}
/// Loads module `T` with optional template parameters `Ts...`. /// Loads module `T` with optional template parameters `Ts...`.
template <class T, class... Ts> template <class T, class... Ts>
actor_system_config& load() { actor_system_config& load() {
...@@ -272,10 +245,6 @@ public: ...@@ -272,10 +245,6 @@ public:
/// @note Has no effect unless building CAF with CAF_ENABLE_ACTOR_PROFILER. /// @note Has no effect unless building CAF with CAF_ENABLE_ACTOR_PROFILER.
tracing_data_factory* tracing_context = nullptr; tracing_data_factory* tracing_context = nullptr;
// -- rendering of user-defined types ----------------------------------------
error_renderer_map error_renderers;
// -- parsing parameters ----------------------------------------------------- // -- parsing parameters -----------------------------------------------------
/// Configures the file path for the INI file, `caf-application.ini` per /// Configures the file path for the INI file, `caf-application.ini` per
...@@ -291,13 +260,8 @@ public: ...@@ -291,13 +260,8 @@ public:
// -- default error rendering functions -------------------------------------- // -- default error rendering functions --------------------------------------
static std::string render(const error& err); [[deprecated("please use to_string() on the error")]] static std::string
render(const error& err);
static std::string render_sec(uint8_t, const message&);
static std::string render_exit_reason(uint8_t, const message&);
static std::string render_pec(uint8_t, const message&);
// -- config file parsing ---------------------------------------------------- // -- config file parsing ----------------------------------------------------
......
// Deprecated include. The next CAF release won't include this header.
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <type_traits>
namespace caf::detail {
template <class T, std::size_t = sizeof(T)>
std::true_type is_complete_impl(T*);
std::false_type is_complete_impl(...);
/// Checks whether T is a complete type. For example, passing a forward
/// declaration or undefined template specialization evaluates to `false`.
template <class T>
constexpr bool is_complete
= decltype(is_complete_impl(std::declval<T*>()))::value;
} // namespace caf::detail
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "caf/detail/is_complete.hpp"
#include "caf/detail/is_one_of.hpp" #include "caf/detail/is_one_of.hpp"
#include "caf/detail/type_list.hpp" #include "caf/detail/type_list.hpp"
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
...@@ -741,17 +742,6 @@ struct is_stl_tuple_type { ...@@ -741,17 +742,6 @@ struct is_stl_tuple_type {
template <class T> template <class T>
constexpr bool is_stl_tuple_type_v = is_stl_tuple_type<T>::value; constexpr bool is_stl_tuple_type_v = is_stl_tuple_type<T>::value;
template <class T, std::size_t = sizeof(T)>
std::true_type is_complete_impl(T*);
std::false_type is_complete_impl(...);
/// Checks whether T is a complete type. For example, passing a forward
/// declaration or undefined template specialization evaluates to `false`.
template <class T>
constexpr bool is_complete
= decltype(is_complete_impl(std::declval<T*>()))::value;
} // namespace caf::detail } // namespace caf::detail
#undef CAF_HAS_MEMBER_TRAIT #undef CAF_HAS_MEMBER_TRAIT
......
...@@ -19,20 +19,21 @@ ...@@ -19,20 +19,21 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <functional> #include <memory>
#include <utility> #include <utility>
#include "caf/detail/comparable.hpp" #include "caf/detail/comparable.hpp"
#include "caf/detail/core_export.hpp" #include "caf/detail/core_export.hpp"
#include "caf/error_category.hpp"
#include "caf/error_code.hpp" #include "caf/error_code.hpp"
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/is_error_code_enum.hpp"
#include "caf/message.hpp" #include "caf/message.hpp"
#include "caf/meta/load_callback.hpp" #include "caf/meta/load_callback.hpp"
#include "caf/meta/omittable_if_empty.hpp" #include "caf/meta/omittable_if_empty.hpp"
#include "caf/meta/save_callback.hpp" #include "caf/meta/save_callback.hpp"
#include "caf/meta/type_name.hpp" #include "caf/meta/type_name.hpp"
#include "caf/none.hpp" #include "caf/none.hpp"
#include "caf/type_id.hpp"
namespace caf { namespace caf {
...@@ -68,38 +69,33 @@ namespace caf { ...@@ -68,38 +69,33 @@ namespace caf {
/// rendering error messages via `actor_system::render(const error&)`. /// rendering error messages via `actor_system::render(const error&)`.
class CAF_CORE_EXPORT error : detail::comparable<error> { class CAF_CORE_EXPORT error : detail::comparable<error> {
public: public:
// -- member types -----------------------------------------------------------
using inspect_fun
= std::function<error(meta::type_name_t, uint8_t&, uint8_t&,
meta::omittable_if_empty_t, message&)>;
// -- constructors, destructors, and assignment operators -------------------- // -- constructors, destructors, and assignment operators --------------------
error() noexcept; error() noexcept = default;
error(none_t) noexcept; error(none_t) noexcept;
error(error&&) noexcept; error(error&&) noexcept = default;
error& operator=(error&&) noexcept; error& operator=(error&&) noexcept = default;
error(const error&); error(const error&);
error& operator=(const error&); error& operator=(const error&);
error(uint8_t x, uint8_t y); template <class Enum, class = std::enable_if_t<is_error_code_enum_v<Enum>>>
error(Enum code) : error(static_cast<uint8_t>(code), type_id_v<Enum>) {
error(uint8_t x, uint8_t y, message z); // nop
}
template <class Enum, uint8_t Category = error_category<Enum>::value> template <class Enum, class = std::enable_if_t<is_error_code_enum_v<Enum>>>
error(Enum error_value) : error(static_cast<uint8_t>(error_value), Category) { error(Enum code, message context)
: error(static_cast<uint8_t>(code), type_id_v<Enum>, std::move(context)) {
// nop // nop
} }
template <class Enum> template <class Enum>
error(error_code<Enum> code) error(error_code<Enum> code) : error(to_integer(code), type_id_v<Enum>) {
: error(static_cast<uint8_t>(code.value()), error_category<Enum>::value) {
// nop // nop
} }
...@@ -115,21 +111,25 @@ public: ...@@ -115,21 +111,25 @@ public:
return *this = code.value(); return *this = code.value();
} }
~error(); // -- properties -------------------------------------------------------------
// -- observers --------------------------------------------------------------
/// Returns the category-specific error code, whereas `0` means "no error". /// Returns the category-specific error code, whereas `0` means "no error".
/// @pre `*this != none` /// @pre `*this != none`
uint8_t code() const noexcept; uint8_t code() const noexcept {
return data_->code;
}
/// Returns the category of this error. /// Returns the ::type_id of the category for this error.
/// @pre `*this != none` /// @pre `*this != none`
uint8_t category() const noexcept; type_id_t category() const noexcept {
return data_->category;
}
/// Returns context information to this error. /// Returns context information to this error.
/// @pre `*this != none` /// @pre `*this != none`
const message& context() const noexcept; const message& context() const noexcept {
return data_->context;
}
/// Returns `*this != none`. /// Returns `*this != none`.
explicit operator bool() const noexcept { explicit operator bool() const noexcept {
...@@ -143,23 +143,14 @@ public: ...@@ -143,23 +143,14 @@ public:
int compare(const error&) const noexcept; int compare(const error&) const noexcept;
int compare(uint8_t x, uint8_t y) const noexcept; int compare(uint8_t code, type_id_t category) const noexcept;
// -- modifiers --------------------------------------------------------------
/// Returns context information to this error.
/// @pre `*this != none`
message& context() noexcept;
/// Sets the error code to 0.
void clear() noexcept;
// -- static convenience functions ------------------------------------------- // -- static convenience functions -------------------------------------------
/// @cond PRIVATE /// @cond PRIVATE
static error eval() { static error eval() {
return none; return error{};
} }
template <class F, class... Fs> template <class F, class... Fs>
...@@ -185,36 +176,39 @@ public: ...@@ -185,36 +176,39 @@ public:
uint8_t code = 0; uint8_t code = 0;
auto cb = meta::load_callback([&] { auto cb = meta::load_callback([&] {
if (code == 0) { if (code == 0) {
x.clear(); x.data_.reset();
if constexpr (std::is_same<result_type, void>::value) if constexpr (std::is_same<result_type, void>::value)
return; return;
else else
return result_type{}; return result_type{};
} }
x.init(); if (!x.data_)
x.code_ref() = code; x.data_.reset(new data);
return f(x.category_ref(), x.context()); x.data_->code = code;
return f(x.data_->category, x.data_->context);
}); });
return f(code, cb); return f(code, cb);
} }
} }
private: private:
// -- inspection support ----------------------------------------------------- // -- constructors, destructors, and assignment operators --------------------
uint8_t& code_ref() noexcept;
uint8_t& category_ref() noexcept; error(uint8_t code, type_id_t category);
void init(); error(uint8_t code, type_id_t category, message context);
// -- nested classes --------------------------------------------------------- // -- nested classes ---------------------------------------------------------
struct data; struct data {
uint8_t code;
type_id_t category;
message context;
};
// -- member variables ------------------------------------------------------- // -- member variables -------------------------------------------------------
data* data_; std::unique_ptr<data> data_;
}; };
/// @relates error /// @relates error
...@@ -222,15 +216,15 @@ CAF_CORE_EXPORT std::string to_string(const error& x); ...@@ -222,15 +216,15 @@ CAF_CORE_EXPORT std::string to_string(const error& x);
/// @relates error /// @relates error
template <class Enum> template <class Enum>
error make_error(Enum code) { std::enable_if_t<is_error_code_enum_v<Enum>, error> make_error(Enum code) {
return error{static_cast<uint8_t>(code), error_category<Enum>::value}; return error{code};
} }
/// @relates error /// @relates error
template <class Enum, class T, class... Ts> template <class Enum, class T, class... Ts>
error make_error(Enum code, T&& x, Ts&&... xs) { std::enable_if_t<is_error_code_enum_v<Enum>, error>
return error{static_cast<uint8_t>(code), error_category<Enum>::value, make_error(Enum code, T&& x, Ts&&... xs) {
make_message(std::forward<T>(x), std::forward<Ts>(xs)...)}; return error{code, make_message(std::forward<T>(x), std::forward<Ts>(xs)...)};
} }
/// @relates error /// @relates error
...@@ -244,15 +238,18 @@ inline bool operator==(none_t, const error& x) { ...@@ -244,15 +238,18 @@ inline bool operator==(none_t, const error& x) {
} }
/// @relates error /// @relates error
template <class Enum, uint8_t Category = error_category<Enum>::value> template <class Enum>
bool operator==(const error& x, Enum y) { std::enable_if_t<is_error_code_enum_v<Enum>, bool>
operator==(const error& x, Enum y) {
auto code = static_cast<uint8_t>(y); auto code = static_cast<uint8_t>(y);
return code == 0 ? !x : x && x.category() == Category && x.code() == code; return code == 0 ? !x
: x && x.code() == code && x.category() == type_id_v<Enum>;
} }
/// @relates error /// @relates error
template <class Enum, uint8_t Category = error_category<Enum>::value> template <class Enum>
bool operator==(Enum x, const error& y) { std::enable_if_t<is_error_code_enum_v<Enum>, bool>
operator==(Enum x, const error& y) {
return y == x; return y == x;
} }
...@@ -267,14 +264,16 @@ inline bool operator!=(none_t, const error& x) { ...@@ -267,14 +264,16 @@ inline bool operator!=(none_t, const error& x) {
} }
/// @relates error /// @relates error
template <class Enum, uint8_t Category = error_category<Enum>::value> template <class Enum>
bool operator!=(const error& x, Enum y) { std::enable_if_t<is_error_code_enum_v<Enum>, bool>
operator!=(const error& x, Enum y) {
return !(x == y); return !(x == y);
} }
/// @relates error /// @relates error
template <class Enum, uint8_t Category = error_category<Enum>::value> template <class Enum>
bool operator!=(Enum x, const error& y) { std::enable_if_t<is_error_code_enum_v<Enum>, bool>
operator!=(Enum x, const error& y) {
return !(x == y); return !(x == y);
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <type_traits> #include <type_traits>
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/is_error_code_enum.hpp"
#include "caf/none.hpp" #include "caf/none.hpp"
namespace caf { namespace caf {
...@@ -32,7 +33,11 @@ class error_code { ...@@ -32,7 +33,11 @@ class error_code {
public: public:
using enum_type = Enum; using enum_type = Enum;
using underlying_type = std::underlying_type_t<enum_type>; using underlying_type = typename std::underlying_type<enum_type>::type;
static_assert(is_error_code_enum_v<Enum>);
static_assert(std::is_same<underlying_type, uint8_t>::value);
constexpr error_code() noexcept : value_(static_cast<Enum>(0)) { constexpr error_code() noexcept : value_(static_cast<Enum>(0)) {
// nop // nop
...@@ -67,6 +72,12 @@ private: ...@@ -67,6 +72,12 @@ private:
enum_type value_; enum_type value_;
}; };
/// Returns the value of the underlying integer type of `x`.
template <class Enum, class = std::enable_if_t<is_error_code_enum_v<Enum>>>
constexpr auto to_integer(error_code<Enum> x) noexcept {
return static_cast<typename error_code<Enum>::underlying_type>(x.value());
}
/// Converts `x` to a string if `Enum` provides a `to_string` function. /// Converts `x` to a string if `Enum` provides a `to_string` function.
template <class Enum> template <class Enum>
auto to_string(error_code<Enum> x) -> decltype(to_string(x.value())) { auto to_string(error_code<Enum> x) -> decltype(to_string(x.value())) {
......
...@@ -92,8 +92,8 @@ int exec_main(F fun, int argc, char** argv, ...@@ -92,8 +92,8 @@ int exec_main(F fun, int argc, char** argv,
// Pass CLI options to config. // Pass CLI options to config.
typename helper::config cfg; typename helper::config cfg;
if (auto err = cfg.parse(argc, argv, config_file_name)) { if (auto err = cfg.parse(argc, argv, config_file_name)) {
std::cerr << "error while parsing CLI and file options: " std::cerr << "error while parsing CLI and file options: " << to_string(err)
<< actor_system_config::render(err) << std::endl; << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// Return immediately if a help text was printed. // Return immediately if a help text was printed.
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <string> #include <string>
#include "caf/detail/core_export.hpp" #include "caf/detail/core_export.hpp"
#include "caf/error_category.hpp" #include "caf/is_error_code_enum.hpp"
namespace caf { namespace caf {
...@@ -56,8 +56,8 @@ enum class exit_reason : uint8_t { ...@@ -56,8 +56,8 @@ enum class exit_reason : uint8_t {
CAF_CORE_EXPORT std::string to_string(exit_reason); CAF_CORE_EXPORT std::string to_string(exit_reason);
template <> template <>
struct error_category<exit_reason> { struct is_error_code_enum<exit_reason> {
static constexpr uint8_t value = 3; static constexpr bool value = true;
}; };
} // namespace caf } // namespace caf
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include "caf/deep_to_string.hpp" #include "caf/deep_to_string.hpp"
#include "caf/error.hpp" #include "caf/error.hpp"
#include "caf/error_category.hpp" #include "caf/is_error_code_enum.hpp"
#include "caf/unifyn.hpp" #include "caf/unifyn.hpp"
#include "caf/unit.hpp" #include "caf/unit.hpp"
...@@ -81,9 +81,9 @@ public: ...@@ -81,9 +81,9 @@ public:
construct(other); construct(other);
} }
template <class Enum, uint8_t Category = error_category<Enum>::value> template <class Enum, class = std::enable_if_t<is_error_code_enum_v<Enum>>>
expected(Enum code) : engaged_(false) { expected(Enum code) : engaged_(false) {
new (std::addressof(error_)) caf::error(make_error(code)); new (std::addressof(error_)) caf::error(code);
} }
expected(expected&& other) noexcept(nothrow_move) { expected(expected&& other) noexcept(nothrow_move) {
...@@ -157,7 +157,7 @@ public: ...@@ -157,7 +157,7 @@ public:
return *this; return *this;
} }
template <class Enum, uint8_t Category = error_category<Enum>::value> template <class Enum, class = std::enable_if_t<is_error_code_enum_v<Enum>>>
expected& operator=(Enum code) { expected& operator=(Enum code) {
return *this = make_error(code); return *this = make_error(code);
} }
...@@ -298,14 +298,16 @@ bool operator==(const error& x, const expected<T>& y) { ...@@ -298,14 +298,16 @@ bool operator==(const error& x, const expected<T>& y) {
} }
/// @relates expected /// @relates expected
template <class T, class Enum, uint8_t = error_category<Enum>::value> template <class T, class Enum>
bool operator==(const expected<T>& x, Enum y) { std::enable_if_t<is_error_code_enum_v<Enum>, bool>
operator==(const expected<T>& x, Enum y) {
return x == make_error(y); return x == make_error(y);
} }
/// @relates expected /// @relates expected
template <class Enum, class T, uint8_t = error_category<Enum>::value> template <class T, class Enum>
bool operator==(Enum x, const expected<T>& y) { std::enable_if_t<is_error_code_enum_v<Enum>, bool>
operator==(Enum x, const expected<T>& y) {
return y == make_error(x); return y == make_error(x);
} }
...@@ -341,14 +343,16 @@ bool operator!=(const error& x, const expected<T>& y) { ...@@ -341,14 +343,16 @@ bool operator!=(const error& x, const expected<T>& y) {
} }
/// @relates expected /// @relates expected
template <class T, class Enum, uint8_t = error_category<Enum>::value> template <class T, class Enum>
bool operator!=(const expected<T>& x, Enum y) { std::enable_if_t<is_error_code_enum_v<Enum>, bool>
operator!=(const expected<T>& x, Enum y) {
return !(x == y); return !(x == y);
} }
/// @relates expected /// @relates expected
template <class T, class Enum, uint8_t = error_category<Enum>::value> template <class T, class Enum>
bool operator!=(Enum x, const expected<T>& y) { std::enable_if_t<is_error_code_enum_v<Enum>, bool>
operator!=(Enum x, const expected<T>& y) {
return !(x == y); return !(x == y);
} }
...@@ -375,7 +379,7 @@ public: ...@@ -375,7 +379,7 @@ public:
// nop // nop
} }
template <class Enum, uint8_t = error_category<Enum>::value> template <class Enum, class = std::enable_if_t<is_error_code_enum_v<Enum>>>
expected(Enum code) : error_(code) { expected(Enum code) : error_(code) {
// nop // nop
} }
......
...@@ -181,10 +181,11 @@ config_option make_config_option(T& storage, string_view category, ...@@ -181,10 +181,11 @@ config_option make_config_option(T& storage, string_view category,
// -- enums -------------------------------------------------------------------- // -- enums --------------------------------------------------------------------
enum class byte : uint8_t; enum class byte : uint8_t;
enum class exit_reason : uint8_t;
enum class invoke_message_result;
enum class pec : uint8_t; enum class pec : uint8_t;
enum class sec : uint8_t; enum class sec : uint8_t;
enum class stream_priority; enum class stream_priority;
enum class invoke_message_result;
// -- aliases ------------------------------------------------------------------ // -- aliases ------------------------------------------------------------------
......
...@@ -18,13 +18,17 @@ ...@@ -18,13 +18,17 @@
#pragma once #pragma once
#include <cstdint>
namespace caf { namespace caf {
/// Customization point for enabling conversion from an enum type to an /// Customization point for enabling conversion from an enum type to an
/// @ref error. /// @ref error or @ref error_code.
template <class T>
struct is_error_code_enum {
static constexpr bool value = false;
};
/// @relates is_error_code_enum
template <class T> template <class T>
struct error_category; constexpr bool is_error_code_enum_v = is_error_code_enum<T>::value;
} // namespace caf } // namespace caf
// Deprecated include. The next CAF release won't include this header.
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
#include <string> #include <string>
#include "caf/detail/core_export.hpp" #include "caf/detail/core_export.hpp"
#include "caf/error_category.hpp"
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/is_error_code_enum.hpp"
namespace caf { namespace caf {
...@@ -80,8 +80,8 @@ enum class pec : uint8_t { ...@@ -80,8 +80,8 @@ enum class pec : uint8_t {
CAF_CORE_EXPORT std::string to_string(pec); CAF_CORE_EXPORT std::string to_string(pec);
template <> template <>
struct error_category<pec> { struct is_error_code_enum<pec> {
static constexpr uint8_t value = 1; static constexpr bool value = true;
}; };
} // namespace caf } // namespace caf
...@@ -62,7 +62,7 @@ public: ...@@ -62,7 +62,7 @@ public:
result_base& operator=(const result_base&) = default; result_base& operator=(const result_base&) = default;
template <class Enum, uint8_t = error_category<Enum>::value> template <class Enum, class = std::enable_if_t<is_error_code_enum_v<Enum>>>
result_base(Enum x) : content_(make_error(x)) { result_base(Enum x) : content_(make_error(x)) {
// nop // nop
} }
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
#include <string> #include <string>
#include "caf/detail/core_export.hpp" #include "caf/detail/core_export.hpp"
#include "caf/error_category.hpp"
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/is_error_code_enum.hpp"
namespace caf { namespace caf {
...@@ -147,11 +147,12 @@ enum class sec : uint8_t { ...@@ -147,11 +147,12 @@ enum class sec : uint8_t {
all_requests_failed, all_requests_failed,
}; };
/// @relates sec
CAF_CORE_EXPORT std::string to_string(sec); CAF_CORE_EXPORT std::string to_string(sec);
template <> template <>
struct error_category<sec> { struct is_error_code_enum<sec> {
static constexpr uint8_t value = 0; static constexpr bool value = true;
}; };
} // namespace caf } // namespace caf
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <utility> #include <utility>
#include "caf/detail/core_export.hpp" #include "caf/detail/core_export.hpp"
#include "caf/detail/is_complete.hpp"
#include "caf/detail/pp.hpp" #include "caf/detail/pp.hpp"
#include "caf/detail/squashed_int.hpp" #include "caf/detail/squashed_int.hpp"
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
...@@ -83,6 +84,10 @@ constexpr const char* type_name_v = type_name<T>::value; ...@@ -83,6 +84,10 @@ constexpr const char* type_name_v = type_name<T>::value;
/// The first type ID not reserved by CAF and its modules. /// The first type ID not reserved by CAF and its modules.
constexpr type_id_t first_custom_type_id = 200; constexpr type_id_t first_custom_type_id = 200;
/// Checks whether `type_id` is specialized for `T`.
template <class T>
constexpr bool has_type_id = detail::is_complete<type_id<T>>;
} // namespace caf } // namespace caf
/// Starts a code block for registering custom types to CAF. Stores the first ID /// Starts a code block for registering custom types to CAF. Stores the first ID
...@@ -243,6 +248,7 @@ CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0) ...@@ -243,6 +248,7 @@ CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0)
CAF_ADD_TYPE_ID(core_module, (caf::downstream_msg)) CAF_ADD_TYPE_ID(core_module, (caf::downstream_msg))
CAF_ADD_TYPE_ID(core_module, (caf::error)) CAF_ADD_TYPE_ID(core_module, (caf::error))
CAF_ADD_TYPE_ID(core_module, (caf::exit_msg)) CAF_ADD_TYPE_ID(core_module, (caf::exit_msg))
CAF_ADD_TYPE_ID(core_module, (caf::exit_reason))
CAF_ADD_TYPE_ID(core_module, (caf::group)) CAF_ADD_TYPE_ID(core_module, (caf::group))
CAF_ADD_TYPE_ID(core_module, (caf::group_down_msg)) CAF_ADD_TYPE_ID(core_module, (caf::group_down_msg))
CAF_ADD_TYPE_ID(core_module, (caf::message)) CAF_ADD_TYPE_ID(core_module, (caf::message))
...@@ -250,6 +256,8 @@ CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0) ...@@ -250,6 +256,8 @@ CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0)
CAF_ADD_TYPE_ID(core_module, (caf::node_down_msg)) CAF_ADD_TYPE_ID(core_module, (caf::node_down_msg))
CAF_ADD_TYPE_ID(core_module, (caf::node_id)) CAF_ADD_TYPE_ID(core_module, (caf::node_id))
CAF_ADD_TYPE_ID(core_module, (caf::open_stream_msg)) CAF_ADD_TYPE_ID(core_module, (caf::open_stream_msg))
CAF_ADD_TYPE_ID(core_module, (caf::pec))
CAF_ADD_TYPE_ID(core_module, (caf::sec))
CAF_ADD_TYPE_ID(core_module, (caf::strong_actor_ptr)) CAF_ADD_TYPE_ID(core_module, (caf::strong_actor_ptr))
CAF_ADD_TYPE_ID(core_module, (caf::timeout_msg)) CAF_ADD_TYPE_ID(core_module, (caf::timeout_msg))
CAF_ADD_TYPE_ID(core_module, (caf::timespan)) CAF_ADD_TYPE_ID(core_module, (caf::timespan))
......
...@@ -364,12 +364,6 @@ actor_registry& actor_system::registry() { ...@@ -364,12 +364,6 @@ actor_registry& actor_system::registry() {
} }
std::string actor_system::render(const error& x) const { std::string actor_system::render(const error& x) const {
if (!x)
return to_string(x);
auto& xs = config().error_renderers;
auto i = xs.find(x.category());
if (i != xs.end())
return i->second(x.code(), x.context());
return to_string(x); return to_string(x);
} }
......
...@@ -136,10 +136,6 @@ actor_system_config::actor_system_config() ...@@ -136,10 +136,6 @@ actor_system_config::actor_system_config()
"path to an OpenSSL-style directory of trusted certificates") "path to an OpenSSL-style directory of trusted certificates")
.add<string>(openssl_cafile, "cafile", .add<string>(openssl_cafile, "cafile",
"path to a file of concatenated PEM-formatted certificates"); "path to a file of concatenated PEM-formatted certificates");
// add renderers for default error categories
add_error_category(error_category<sec>::value, render_sec);
add_error_category(error_category<pec>::value, render_pec);
add_error_category(error_category<exit_reason>::value, render_exit_reason);
} }
settings actor_system_config::dump_content() const { settings actor_system_config::dump_content() const {
...@@ -358,14 +354,8 @@ actor_system_config& actor_system_config::add_actor_factory(std::string name, ...@@ -358,14 +354,8 @@ actor_system_config& actor_system_config::add_actor_factory(std::string name,
return *this; return *this;
} }
actor_system_config& actor_system_config::add_error_category(uint8_t x, actor_system_config& actor_system_config::set_impl(string_view name,
error_renderer y) { config_value value) {
error_renderers[x] = y;
return *this;
}
actor_system_config&
actor_system_config::set_impl(string_view name, config_value value) {
if (name == "middleman.app-identifier") { if (name == "middleman.app-identifier") {
// TODO: Print a warning with 0.18 and remove this code with 0.19. // TODO: Print a warning with 0.18 and remove this code with 0.19.
value.convert_to_list(); value.convert_to_list();
...@@ -393,39 +383,9 @@ timespan actor_system_config::stream_tick_duration() const noexcept { ...@@ -393,39 +383,9 @@ timespan actor_system_config::stream_tick_duration() const noexcept {
stream_max_batch_delay.count()); stream_max_batch_delay.count());
return timespan{ns_count}; return timespan{ns_count};
} }
std::string actor_system_config::render(const error& x) {
if (!x)
return "none";
switch (x.category()) {
case error_category<sec>::value:
return render_sec(x.code(), x.context());
case error_category<exit_reason>::value:
return render_exit_reason(x.code(), x.context());
case error_category<pec>::value:
return render_pec(x.code(), x.context());
default:
return deep_to_string(meta::type_name("error"), x.code(), x.category(),
meta::omittable_if_empty(), x.context());
}
}
std::string actor_system_config::render_sec(uint8_t x, const message& xs) { std::string actor_system_config::render(const error& x) {
auto tmp = static_cast<sec>(x); return to_string(x);
return deep_to_string(meta::type_name("system_error"), tmp,
meta::omittable_if_empty(), xs);
}
std::string actor_system_config::render_exit_reason(uint8_t x,
const message& xs) {
auto tmp = static_cast<exit_reason>(x);
return deep_to_string(meta::type_name("exit_reason"), tmp,
meta::omittable_if_empty(), xs);
}
std::string actor_system_config::render_pec(uint8_t x, const message& xs) {
auto tmp = static_cast<pec>(x);
return deep_to_string(meta::type_name("parser_error"), tmp,
meta::omittable_if_empty(), xs);
} }
expected<settings> expected<settings>
......
...@@ -157,7 +157,7 @@ auto config_option_set::parse(settings& config, argument_iterator first, ...@@ -157,7 +157,7 @@ auto config_option_set::parse(settings& config, argument_iterator first,
auto val = opt.parse(slice); auto val = opt.parse(slice);
if (!val) { if (!val) {
auto& err = val.error(); auto& err = val.error();
if (err.category() == error_category<pec>::value) if (err.category() == type_id_v<pec>)
return static_cast<pec>(err.code()); return static_cast<pec>(err.code());
return pec::invalid_argument; return pec::invalid_argument;
} }
......
...@@ -22,155 +22,70 @@ ...@@ -22,155 +22,70 @@
#include "caf/config.hpp" #include "caf/config.hpp"
#include "caf/deep_to_string.hpp" #include "caf/deep_to_string.hpp"
#include "caf/deserializer.hpp" #include "caf/deserializer.hpp"
#include "caf/detail/meta_object.hpp"
#include "caf/message.hpp" #include "caf/message.hpp"
#include "caf/serializer.hpp" #include "caf/serializer.hpp"
namespace caf { namespace caf {
// -- nested classes -----------------------------------------------------------
struct error::data {
uint8_t code;
uint8_t category;
message context;
};
// -- constructors, destructors, and assignment operators ---------------------- // -- constructors, destructors, and assignment operators ----------------------
error::error() noexcept : data_(nullptr) {
// nop
}
error::error(none_t) noexcept : data_(nullptr) { error::error(none_t) noexcept : data_(nullptr) {
// nop // nop
} }
error::error(error&& x) noexcept : data_(x.data_) {
if (data_ != nullptr)
x.data_ = nullptr;
}
error& error::operator=(error&& x) noexcept {
if (this != &x)
std::swap(data_, x.data_);
return *this;
}
error::error(const error& x) : data_(x ? new data(*x.data_) : nullptr) { error::error(const error& x) : data_(x ? new data(*x.data_) : nullptr) {
// nop // nop
} }
error& error::operator=(const error& x) { error& error::operator=(const error& x) {
if (this == &x)
return *this;
if (x) { if (x) {
if (data_ == nullptr) if (data_ == nullptr)
data_ = new data(*x.data_); data_.reset(new data(*x.data_));
else else
*data_ = *x.data_; *data_ = *x.data_;
} else { } else {
clear(); data_.reset();
} }
return *this; return *this;
} }
error::error(uint8_t x, uint8_t y) error::error(uint8_t code, type_id_t category)
: data_(x != 0 ? new data{x, y, message{}} : nullptr) { : error(code, category, message{}) {
// nop // nop
} }
error::error(uint8_t x, uint8_t y, message z) error::error(uint8_t code, type_id_t category, message context)
: data_(x != 0 ? new data{x, y, std::move(z)} : nullptr) { : data_(code != 0 ? new data{code, category, std::move(context)} : nullptr) {
// nop // nop
} }
error::~error() {
delete data_;
}
// -- observers ---------------------------------------------------------------- // -- observers ----------------------------------------------------------------
uint8_t error::code() const noexcept {
CAF_ASSERT(data_ != nullptr);
return data_->code;
}
uint8_t error::category() const noexcept {
CAF_ASSERT(data_ != nullptr);
return data_->category;
}
const message& error::context() const noexcept {
CAF_ASSERT(data_ != nullptr);
return data_->context;
}
int error::compare(const error& x) const noexcept { int error::compare(const error& x) const noexcept {
uint8_t x_code; return x ? compare(x.data_->code, x.data_->category) : compare(0, 0);
uint8_t x_category;
if (x) {
x_code = x.data_->code;
x_category = x.data_->category;
} else {
x_code = 0;
x_category = 0;
}
return compare(x_code, x_category);
}
int error::compare(uint8_t x, uint8_t y) const noexcept {
uint8_t mx;
uint8_t my;
if (data_ != nullptr) {
mx = data_->code;
my = data_->category;
} else {
mx = 0;
my = 0;
}
// all errors with default value are considered no error -> equal
if (mx == x && x == 0)
return 0;
if (my < y)
return -1;
if (my > y)
return 1;
return static_cast<int>(mx) - x;
}
// -- modifiers --------------------------------------------------------------
message& error::context() noexcept {
CAF_ASSERT(data_ != nullptr);
return data_->context;
} }
void error::clear() noexcept { int error::compare(uint8_t code, type_id_t category) const noexcept {
if (data_ != nullptr) { int x = 0;
delete data_; if (data_ != nullptr)
data_ = nullptr; x = (data_->code << 16) | data_->category;
} return x - int{(code << 16) | category};
} }
// -- inspection support ----------------------------------------------------- // -- inspection support -----------------------------------------------------
uint8_t& error::code_ref() noexcept {
CAF_ASSERT(data_ != nullptr);
return data_->code;
}
uint8_t& error::category_ref() noexcept {
CAF_ASSERT(data_ != nullptr);
return data_->category;
}
void error::init() {
if (data_ == nullptr)
data_ = new data;
}
std::string to_string(const error& x) { std::string to_string(const error& x) {
return actor_system_config::render(x); if (!x)
return "none";
std::string result;
auto code = x.code();
auto mobj = detail::global_meta_object(x.category());
mobj->stringify(result, &code);
auto ctx = x.context();
if (ctx)
result += to_string(ctx);
return result;
} }
} // namespace caf } // namespace caf
...@@ -54,11 +54,11 @@ CAF_TEST(serialization roundtrips go through the registry) { ...@@ -54,11 +54,11 @@ CAF_TEST(serialization roundtrips go through the registry) {
byte_buffer buf; byte_buffer buf;
binary_serializer sink{sys, buf}; binary_serializer sink{sys, buf};
if (auto err = sink(hdl)) if (auto err = sink(hdl))
CAF_FAIL("serialization failed: " << sys.render(err)); CAF_FAIL("serialization failed: " << to_string(err));
actor hdl2; actor hdl2;
binary_deserializer source{sys, buf}; binary_deserializer source{sys, buf};
if (auto err = source(hdl2)) if (auto err = source(hdl2))
CAF_FAIL("serialization failed: " << sys.render(err)); CAF_FAIL("serialization failed: " << to_string(err));
CAF_CHECK_EQUAL(hdl, hdl2); CAF_CHECK_EQUAL(hdl, hdl2);
anon_send_exit(hdl, exit_reason::user_shutdown); anon_send_exit(hdl, exit_reason::user_shutdown);
} }
......
...@@ -71,7 +71,7 @@ struct fixture { ...@@ -71,7 +71,7 @@ struct fixture {
cfg.remainder.clear(); cfg.remainder.clear();
std::istringstream ini{file_content}; std::istringstream ini{file_content};
if (auto err = cfg.parse(std::move(args), ini)) if (auto err = cfg.parse(std::move(args), ini))
CAF_FAIL("parse() failed: " << cfg.render(err)); CAF_FAIL("parse() failed: " << err);
} }
}; };
......
...@@ -49,8 +49,7 @@ struct fixture { ...@@ -49,8 +49,7 @@ struct fixture {
auto result = T{}; auto result = T{};
binary_deserializer source{nullptr, buf}; binary_deserializer source{nullptr, buf};
if (auto err = source(result)) if (auto err = source(result))
CAF_FAIL("binary_deserializer failed to load: " CAF_FAIL("binary_deserializer failed to load: " << to_string(err));
<< actor_system_config::render(err));
return result; return result;
} }
...@@ -58,8 +57,7 @@ struct fixture { ...@@ -58,8 +57,7 @@ struct fixture {
void load(const std::vector<byte>& buf, Ts&... xs) { void load(const std::vector<byte>& buf, Ts&... xs) {
binary_deserializer source{nullptr, buf}; binary_deserializer source{nullptr, buf};
if (auto err = source(xs...)) if (auto err = source(xs...))
CAF_FAIL("binary_deserializer failed to load: " CAF_FAIL("binary_deserializer failed to load: " << to_string(err));
<< actor_system_config::render(err));
} }
}; };
......
...@@ -49,8 +49,7 @@ struct fixture { ...@@ -49,8 +49,7 @@ struct fixture {
byte_buffer result; byte_buffer result;
binary_serializer sink{nullptr, result}; binary_serializer sink{nullptr, result};
if (auto err = sink(xs...)) if (auto err = sink(xs...))
CAF_FAIL("binary_serializer failed to save: " CAF_FAIL("binary_serializer failed to save: " << err);
<< actor_system_config::render(err));
return result; return result;
} }
...@@ -58,8 +57,7 @@ struct fixture { ...@@ -58,8 +57,7 @@ struct fixture {
void save_to_buf(byte_buffer& data, const Ts&... xs) { void save_to_buf(byte_buffer& data, const Ts&... xs) {
binary_serializer sink{nullptr, data}; binary_serializer sink{nullptr, data};
if (auto err = sink(xs...)) if (auto err = sink(xs...))
CAF_FAIL("binary_serializer failed to save: " CAF_FAIL("binary_serializer failed to save: " << err);
<< actor_system_config::render(err));
} }
}; };
......
...@@ -221,7 +221,7 @@ CAF_TEST(adaptor access from actor system config - file input) { ...@@ -221,7 +221,7 @@ CAF_TEST(adaptor access from actor system config - file input) {
test_config cfg; test_config cfg;
std::istringstream in{config_text}; std::istringstream in{config_text};
if (auto err = cfg.parse(0, nullptr, in)) if (auto err = cfg.parse(0, nullptr, in))
CAF_FAIL("cfg.parse failed: " << cfg.render(err)); CAF_FAIL("cfg.parse failed: " << err);
CAF_CHECK_EQUAL(cfg.max_delay, my_duration::from_s(123)); CAF_CHECK_EQUAL(cfg.max_delay, my_duration::from_s(123));
} }
...@@ -232,7 +232,7 @@ CAF_TEST(adaptor access from actor system config - file input and arguments) { ...@@ -232,7 +232,7 @@ CAF_TEST(adaptor access from actor system config - file input and arguments) {
test_config cfg; test_config cfg;
std::istringstream in{config_text}; std::istringstream in{config_text};
if (auto err = cfg.parse(std::move(args), in)) if (auto err = cfg.parse(std::move(args), in))
CAF_FAIL("cfg.parse failed: " << cfg.render(err)); CAF_FAIL("cfg.parse failed: " << err);
CAF_CHECK_EQUAL(cfg.max_delay, my_duration::from_ms(20)); CAF_CHECK_EQUAL(cfg.max_delay, my_duration::from_ms(20));
} }
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "caf/all.hpp" #include "caf/all.hpp"
#define ERROR_HANDLER [&](error& err) { CAF_FAIL(system.render(err)); } #define ERROR_HANDLER [&](error& err) { CAF_FAIL(err); }
using namespace caf; using namespace caf;
......
...@@ -345,9 +345,7 @@ CAF_TEST(ranges can use signed integers) { ...@@ -345,9 +345,7 @@ CAF_TEST(ranges can use signed integers) {
if (auto res = r(expr)) { \ if (auto res = r(expr)) { \
CAF_FAIL("expected expression to produce to an error"); \ CAF_FAIL("expected expression to produce to an error"); \
} else { \ } else { \
auto& err = res.error(); \ CAF_CHECK_EQUAL(res.error(), enum_value); \
CAF_CHECK(err.category() == error_category<pec>::value); \
CAF_CHECK_EQUAL(err.code(), static_cast<uint8_t>(enum_value)); \
} }
CAF_TEST(the parser rejects invalid step values) { CAF_TEST(the parser rejects invalid step values) {
......
...@@ -40,7 +40,7 @@ struct fixture : test_coordinator_fixture<> { ...@@ -40,7 +40,7 @@ struct fixture : test_coordinator_fixture<> {
byte_buffer buf; byte_buffer buf;
binary_serializer sink{sys, buf}; binary_serializer sink{sys, buf};
if (auto err = sink(xs...)) if (auto err = sink(xs...))
CAF_FAIL("failed to serialize data: " << sys.render(err)); CAF_FAIL("failed to serialize data: " << err);
return buf.size(); return buf.size();
} }
}; };
......
...@@ -30,13 +30,13 @@ CAF_TEST(default constructed errors evaluate to false) { ...@@ -30,13 +30,13 @@ CAF_TEST(default constructed errors evaluate to false) {
} }
CAF_TEST(error code zero is not an error) { CAF_TEST(error code zero is not an error) {
CAF_CHECK(!error(0, error_category<sec>::value)); CAF_CHECK(!error(sec::none));
CAF_CHECK(!make_error(sec::none)); CAF_CHECK(!make_error(sec::none));
CAF_CHECK(!error{error_code<sec>(sec::none)}); CAF_CHECK(!error{error_code<sec>(sec::none)});
} }
CAF_TEST(error codes that are not zero are errors) { CAF_TEST(error codes that are not zero are errors) {
CAF_CHECK(error(1, error_category<sec>::value)); CAF_CHECK(error(sec::unexpected_message));
CAF_CHECK(make_error(sec::unexpected_message)); CAF_CHECK(make_error(sec::unexpected_message));
CAF_CHECK(error{error_code<sec>(sec::unexpected_message)}); CAF_CHECK(error{error_code<sec>(sec::unexpected_message)});
} }
......
...@@ -55,11 +55,11 @@ struct fixture { ...@@ -55,11 +55,11 @@ struct fixture {
byte_buffer buf; byte_buffer buf;
binary_serializer sink(sys, buf); binary_serializer sink(sys, buf);
if (auto err = sink(x)) if (auto err = sink(x))
CAF_FAIL("serialization failed: " << sys.render(err)); CAF_FAIL("serialization failed: " << err);
binary_deserializer source(sys, make_span(buf)); binary_deserializer source(sys, make_span(buf));
T y; T y;
if (auto err = source(y)) if (auto err = source(y))
CAF_FAIL("deserialization failed: " << sys.render(err)); CAF_FAIL("deserialization failed: " << err);
return y; return y;
} }
}; };
......
...@@ -55,11 +55,11 @@ struct fixture { ...@@ -55,11 +55,11 @@ struct fixture {
byte_buffer buf; byte_buffer buf;
binary_serializer sink(sys, buf); binary_serializer sink(sys, buf);
if (auto err = sink(x)) if (auto err = sink(x))
CAF_FAIL("serialization failed: " << sys.render(err)); CAF_FAIL("serialization failed: " << err);
binary_deserializer source(sys, make_span(buf)); binary_deserializer source(sys, make_span(buf));
T y; T y;
if (auto err = source(y)) if (auto err = source(y))
CAF_FAIL("deserialization failed: " << sys.render(err)); CAF_FAIL("deserialization failed: " << err);
return y; return y;
} }
}; };
......
...@@ -291,7 +291,7 @@ CAF_TEST(object access from actor system config - file input) { ...@@ -291,7 +291,7 @@ CAF_TEST(object access from actor system config - file input) {
test_config cfg; test_config cfg;
std::istringstream in{config_text}; std::istringstream in{config_text};
if (auto err = cfg.parse(0, nullptr, in)) if (auto err = cfg.parse(0, nullptr, in))
CAF_FAIL("cfg.parse failed: " << cfg.render(err)); CAF_FAIL("cfg.parse failed: " << err);
CAF_CHECK_EQUAL(cfg.fb.foo, 42); CAF_CHECK_EQUAL(cfg.fb.foo, 42);
CAF_CHECK_EQUAL(cfg.fb.bar, "Don't panic!"); CAF_CHECK_EQUAL(cfg.fb.bar, "Don't panic!");
CAF_CHECK_EQUAL(cfg.fbfb.x.foo, 1); CAF_CHECK_EQUAL(cfg.fbfb.x.foo, 1);
...@@ -308,7 +308,7 @@ CAF_TEST(object access from actor system config - file input and arguments) { ...@@ -308,7 +308,7 @@ CAF_TEST(object access from actor system config - file input and arguments) {
test_config cfg; test_config cfg;
std::istringstream in{config_text}; std::istringstream in{config_text};
if (auto err = cfg.parse(std::move(args), in)) if (auto err = cfg.parse(std::move(args), in))
CAF_FAIL("cfg.parse failed: " << cfg.render(err)); CAF_FAIL("cfg.parse failed: " << err);
CAF_CHECK_EQUAL(cfg.fb.foo, 42); CAF_CHECK_EQUAL(cfg.fb.foo, 42);
CAF_CHECK_EQUAL(cfg.fb.bar, "Don't panic!"); CAF_CHECK_EQUAL(cfg.fb.bar, "Don't panic!");
CAF_CHECK_EQUAL(cfg.fbfb.x.foo, 10); CAF_CHECK_EQUAL(cfg.fbfb.x.foo, 10);
......
...@@ -74,7 +74,7 @@ struct fixture : test_coordinator_fixture<> { ...@@ -74,7 +74,7 @@ struct fixture : test_coordinator_fixture<> {
} // namespace } // namespace
#define ERROR_HANDLER [&](error& err) { CAF_FAIL(sys.render(err)); } #define ERROR_HANDLER [&](error& err) { CAF_FAIL(err); }
#define SUBTEST(message) \ #define SUBTEST(message) \
*result = none; \ *result = none; \
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "caf/all.hpp" #include "caf/all.hpp"
#define ERROR_HANDLER [&](error& err) { CAF_FAIL(system.render(err)); } #define ERROR_HANDLER [&](error& err) { CAF_FAIL(err); }
using namespace caf; using namespace caf;
......
...@@ -46,9 +46,7 @@ struct fixture : test_coordinator_fixture<> { ...@@ -46,9 +46,7 @@ struct fixture : test_coordinator_fixture<> {
} }
std::function<void(const error&)> make_error_handler() { std::function<void(const error&)> make_error_handler() {
return [this](const error& err) { return [](const error& err) { CAF_FAIL("unexpected error: " << err); };
CAF_FAIL("unexpected error: " << sys.render(err));
};
} }
std::function<void(const error&)> make_counting_error_handler(size_t* count) { std::function<void(const error&)> make_counting_error_handler(size_t* count) {
......
...@@ -44,9 +44,7 @@ struct fixture : test_coordinator_fixture<> { ...@@ -44,9 +44,7 @@ struct fixture : test_coordinator_fixture<> {
} }
auto make_error_handler() { auto make_error_handler() {
return [this](const error& err) { return [](const error& err) { CAF_FAIL("unexpected error: " << err); };
CAF_FAIL("unexpected error: " << sys.render(err));
};
} }
auto make_counting_error_handler(size_t* count) { auto make_counting_error_handler(size_t* count) {
......
...@@ -107,7 +107,7 @@ struct fixture : test_coordinator_fixture<> { ...@@ -107,7 +107,7 @@ struct fixture : test_coordinator_fixture<> {
binary_serializer sink{sys, buf}; binary_serializer sink{sys, buf};
if (auto err = sink(xs...)) if (auto err = sink(xs...))
CAF_FAIL("serialization failed: " CAF_FAIL("serialization failed: "
<< sys.render(err) << err
<< ", data: " << deep_to_string(std::forward_as_tuple(xs...))); << ", data: " << deep_to_string(std::forward_as_tuple(xs...)));
return buf; return buf;
} }
...@@ -116,7 +116,7 @@ struct fixture : test_coordinator_fixture<> { ...@@ -116,7 +116,7 @@ struct fixture : test_coordinator_fixture<> {
void deserialize(const byte_buffer& buf, Ts&... xs) { void deserialize(const byte_buffer& buf, Ts&... xs) {
binary_deserializer source{sys, buf}; binary_deserializer source{sys, buf};
if (auto err = source(xs...)) if (auto err = source(xs...))
CAF_FAIL("deserialization failed: " << sys.render(err)); CAF_FAIL("deserialization failed: " << err);
} }
// serializes `x` and then deserializes and returns the serialized value // serializes `x` and then deserializes and returns the serialized value
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
# include "caf/all.hpp" # include "caf/all.hpp"
# define ERROR_HANDLER [&](error& err) { CAF_FAIL(sys.render(err)); } # define ERROR_HANDLER [&](error& err) { CAF_FAIL(err); }
using std::string; using std::string;
......
...@@ -95,12 +95,12 @@ using v20 = variant<i01, i02, i03, i04, i05, i06, i07, i08, i09, i10, ...@@ -95,12 +95,12 @@ using v20 = variant<i01, i02, i03, i04, i05, i06, i07, i08, i09, i10,
byte_buffer buf; \ byte_buffer buf; \
binary_serializer sink{sys.dummy_execution_unit(), buf}; \ binary_serializer sink{sys.dummy_execution_unit(), buf}; \
if (auto err = sink(x3)) \ if (auto err = sink(x3)) \
CAF_FAIL("failed to serialize data: " << sys.render(err)); \ CAF_FAIL("failed to serialize data: " << err); \
CAF_CHECK_EQUAL(x3, i##n{0x##n}); \ CAF_CHECK_EQUAL(x3, i##n{0x##n}); \
v20 tmp; \ v20 tmp; \
binary_deserializer source{sys.dummy_execution_unit(), buf}; \ binary_deserializer source{sys.dummy_execution_unit(), buf}; \
if (auto err = source(tmp)) \ if (auto err = source(tmp)) \
CAF_FAIL("failed to deserialize data: " << sys.render(err)); \ CAF_FAIL("failed to deserialize data: " << err); \
CAF_CHECK_EQUAL(tmp, i##n{0x##n}); \ CAF_CHECK_EQUAL(tmp, i##n{0x##n}); \
CAF_CHECK_EQUAL(tmp, x3); \ CAF_CHECK_EQUAL(tmp, x3); \
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "caf/meta/load_callback.hpp" #include "caf/meta/load_callback.hpp"
#include "caf/meta/save_callback.hpp" #include "caf/meta/save_callback.hpp"
#include "caf/meta/type_name.hpp" #include "caf/meta/type_name.hpp"
#include "caf/sec.hpp"
struct sockaddr; struct sockaddr;
struct sockaddr_storage; struct sockaddr_storage;
......
...@@ -318,7 +318,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl, ...@@ -318,7 +318,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
std::set<std::string> sigs; std::set<std::string> sigs;
if (auto err = bd(source_node, app_ids, aid, sigs)) { if (auto err = bd(source_node, app_ids, aid, sigs)) {
CAF_LOG_WARNING("unable to deserialize payload of server handshake:" CAF_LOG_WARNING("unable to deserialize payload of server handshake:"
<< ctx->system().render(err)); << to_string(err));
return serializing_basp_payload_failed; return serializing_basp_payload_failed;
} }
// Check the application ID. // Check the application ID.
...@@ -367,7 +367,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl, ...@@ -367,7 +367,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
node_id source_node; node_id source_node;
if (auto err = bd(source_node)) { if (auto err = bd(source_node)) {
CAF_LOG_WARNING("unable to deserialize payload of client handshake:" CAF_LOG_WARNING("unable to deserialize payload of client handshake:"
<< ctx->system().render(err)); << to_string(err));
return serializing_basp_payload_failed; return serializing_basp_payload_failed;
} }
// Drop repeated handshakes. // Drop repeated handshakes.
...@@ -391,7 +391,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl, ...@@ -391,7 +391,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
if (auto err = bd(source_node, dest_node)) { if (auto err = bd(source_node, dest_node)) {
CAF_LOG_WARNING( CAF_LOG_WARNING(
"unable to deserialize source and destination for routed message:" "unable to deserialize source and destination for routed message:"
<< ctx->system().render(err)); << to_string(err));
return serializing_basp_payload_failed; return serializing_basp_payload_failed;
} }
if (dest_node != this_node_) { if (dest_node != this_node_) {
...@@ -449,7 +449,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl, ...@@ -449,7 +449,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
node_id dest_node; node_id dest_node;
if (auto err = bd(source_node, dest_node)) { if (auto err = bd(source_node, dest_node)) {
CAF_LOG_WARNING("unable to deserialize payload of monitor message:" CAF_LOG_WARNING("unable to deserialize payload of monitor message:"
<< ctx->system().render(err)); << to_string(err));
return serializing_basp_payload_failed; return serializing_basp_payload_failed;
} }
if (dest_node == this_node_) if (dest_node == this_node_)
...@@ -465,8 +465,8 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl, ...@@ -465,8 +465,8 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
node_id dest_node; node_id dest_node;
error fail_state; error fail_state;
if (auto err = bd(source_node, dest_node, fail_state)) { if (auto err = bd(source_node, dest_node, fail_state)) {
CAF_LOG_WARNING("unable to deserialize payload of down message:" CAF_LOG_WARNING(
<< ctx->system().render(err)); "unable to deserialize payload of down message:" << to_string(err));
return serializing_basp_payload_failed; return serializing_basp_payload_failed;
} }
if (dest_node == this_node_) { if (dest_node == this_node_) {
......
...@@ -161,7 +161,7 @@ public: ...@@ -161,7 +161,7 @@ public:
byte_buffer buf; byte_buffer buf;
binary_serializer bs{mpx_, buf}; binary_serializer bs{mpx_, buf};
if (auto err = bs(const_cast<message&>(msg))) if (auto err = bs(const_cast<message&>(msg)))
CAF_FAIL("returned to serialize message: " << sys.render(err)); CAF_FAIL("returned to serialize message: " << to_string(err));
return static_cast<uint32_t>(buf.size()); return static_cast<uint32_t>(buf.size());
} }
...@@ -219,7 +219,7 @@ public: ...@@ -219,7 +219,7 @@ public:
void to_payload(byte_buffer& buf, const Ts&... xs) { void to_payload(byte_buffer& buf, const Ts&... xs) {
binary_serializer sink{mpx_, buf}; binary_serializer sink{mpx_, buf};
if (auto err = sink(xs...)) if (auto err = sink(xs...))
CAF_FAIL("failed to serialize payload: " << sys.render(err)); CAF_FAIL("failed to serialize payload: " << to_string(err));
} }
void to_buf(byte_buffer& buf, basp::header& hdr, payload_writer* writer) { void to_buf(byte_buffer& buf, basp::header& hdr, payload_writer* writer) {
...@@ -347,8 +347,7 @@ public: ...@@ -347,8 +347,7 @@ public:
{ // lifetime scope of source { // lifetime scope of source
binary_deserializer source{this_->mpx(), ob}; binary_deserializer source{this_->mpx(), ob};
if (auto err = source(hdr)) if (auto err = source(hdr))
CAF_FAIL("unable to deserialize header: " CAF_FAIL("unable to deserialize header: " << to_string(err));
<< actor_system_config::render(err));
} }
byte_buffer payload; byte_buffer payload;
if (hdr.payload_len > 0) { if (hdr.payload_len > 0) {
...@@ -485,7 +484,7 @@ CAF_TEST(non_empty_server_handshake) { ...@@ -485,7 +484,7 @@ CAF_TEST(non_empty_server_handshake) {
std::set<std::string> ifs{"caf::replies_to<@u16>::with<@u16>"}; std::set<std::string> ifs{"caf::replies_to<@u16>::with<@u16>"};
binary_serializer sink{nullptr, expected_payload}; binary_serializer sink{nullptr, expected_payload};
if (auto err = sink(instance().this_node(), app_ids, self()->id(), ifs)) if (auto err = sink(instance().this_node(), app_ids, self()->id(), ifs))
CAF_FAIL("serializing handshake failed: " << sys.render(err)); CAF_FAIL("serializing handshake failed: " << to_string(err));
CAF_CHECK_EQUAL(hexstr(payload), hexstr(expected_payload)); CAF_CHECK_EQUAL(hexstr(payload), hexstr(expected_payload));
} }
...@@ -608,7 +607,7 @@ CAF_TEST(remote_actor_and_send) { ...@@ -608,7 +607,7 @@ CAF_TEST(remote_actor_and_send) {
CAF_REQUIRE(proxy == res); CAF_REQUIRE(proxy == res);
result = actor_cast<actor>(res); result = actor_cast<actor>(res);
}, },
[&](error& err) { CAF_FAIL("error: " << sys.render(err)); }); [&](error& err) { CAF_FAIL("error: " << to_string(err)); });
CAF_MESSAGE("send message to proxy"); CAF_MESSAGE("send message to proxy");
anon_send(actor_cast<actor>(result), 42); anon_send(actor_cast<actor>(result), 42);
mpx()->flush_runnables(); mpx()->flush_runnables();
......
...@@ -50,7 +50,7 @@ struct fixture : test_coordinator_fixture<> { ...@@ -50,7 +50,7 @@ struct fixture : test_coordinator_fixture<> {
byte_buffer buf; byte_buffer buf;
binary_serializer sink{sys, buf}; binary_serializer sink{sys, buf};
if (auto err = sink(x, xs...)) if (auto err = sink(x, xs...))
CAF_FAIL("serialization failed: " << sys.render(err)); CAF_FAIL("serialization failed: " << to_string(err));
return buf; return buf;
} }
...@@ -58,7 +58,7 @@ struct fixture : test_coordinator_fixture<> { ...@@ -58,7 +58,7 @@ struct fixture : test_coordinator_fixture<> {
void deserialize(const Buffer& buf, T& x, Ts&... xs) { void deserialize(const Buffer& buf, T& x, Ts&... xs) {
binary_deserializer source{sys, buf}; binary_deserializer source{sys, buf};
if (auto err = source(x, xs...)) if (auto err = source(x, xs...))
CAF_FAIL("serialization failed: " << sys.render(err)); CAF_FAIL("serialization failed: " << to_string(err));
} }
}; };
......
...@@ -109,7 +109,7 @@ CAF_TEST(deliver serialized message) { ...@@ -109,7 +109,7 @@ CAF_TEST(deliver serialized message) {
std::vector<strong_actor_ptr> stages; std::vector<strong_actor_ptr> stages;
binary_serializer sink{sys, payload}; binary_serializer sink{sys, payload};
if (auto err = sink(stages, make_message(ok_atom_v))) if (auto err = sink(stages, make_message(ok_atom_v)))
CAF_FAIL("unable to serialize message: " << sys.render(err)); CAF_FAIL("unable to serialize message: " << err);
io::basp::header hdr{io::basp::message_type::direct_message, io::basp::header hdr{io::basp::message_type::direct_message,
0, 0,
static_cast<uint32_t>(payload.size()), static_cast<uint32_t>(payload.size()),
......
...@@ -845,7 +845,7 @@ public: ...@@ -845,7 +845,7 @@ public:
caf::byte_buffer buf; caf::byte_buffer buf;
caf::binary_serializer sink{sys, buf}; caf::binary_serializer sink{sys, buf};
if (auto err = sink(xs...)) if (auto err = sink(xs...))
CAF_FAIL("serialization failed: " << sys.render(err)); CAF_FAIL("serialization failed: " << err);
return buf; return buf;
} }
...@@ -853,7 +853,7 @@ public: ...@@ -853,7 +853,7 @@ public:
void deserialize(const caf::byte_buffer& buf, Ts&... xs) { void deserialize(const caf::byte_buffer& buf, Ts&... xs) {
caf::binary_deserializer source{sys, buf}; caf::binary_deserializer source{sys, buf};
if (auto err = source(xs...)) if (auto err = source(xs...))
CAF_FAIL("deserialization failed: " << sys.render(err)); CAF_FAIL("deserialization failed: " << err);
} }
template <class T> template <class T>
......
...@@ -99,7 +99,7 @@ as ``CAF_CHECK`` and provide tests rather than implementing a ...@@ -99,7 +99,7 @@ as ``CAF_CHECK`` and provide tests rather than implementing a
}, },
[&](caf::error& err) { [&](caf::error& err) {
// Must not happen, stop test. // Must not happen, stop test.
CAF_FAIL(sys.render(err)); CAF_FAIL(err);
}); });
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment