Flow 2.0.0
Flow project: Full implementation reference.
|
#include "flow/error/error_fwd.hpp"
#include "flow/log/log.hpp"
#include "flow/util/detail/util.hpp"
#include <boost/system/system_error.hpp>
#include <stdexcept>
Go to the source code of this file.
Classes | |
class | flow::error::Runtime_error |
An std::runtime_error (which is an std::exception ) that stores an Error_code. More... | |
Namespaces | |
namespace | flow |
Catch-all namespace for the Flow project: A collection of various production-quality modules written in modern C++17, originally by ygoldfel. | |
namespace | flow::error |
Flow module that facilitates working with error codes and exceptions; essentially comprised of niceties on top boost.system's error facility. | |
Macros | |
#define | FLOW_ERROR_EMIT_ERROR(ARG_val) |
Sets *err_code to ARG_val and logs a warning about the error using FLOW_LOG_WARNING(). More... | |
#define | FLOW_ERROR_EMIT_ERROR_LOG_INFO(ARG_val) |
Identical to FLOW_ERROR_EMIT_ERROR(), but the message logged has flow::log::Sev::S_INFO severity instead of S_WARNING . More... | |
#define | FLOW_ERROR_LOG_ERROR(ARG_val) |
Logs a warning about the given error code using FLOW_LOG_WARNING(). More... | |
#define | FLOW_ERROR_SYS_ERROR_LOG_WARNING() FLOW_LOG_WARNING("System error occurred: [" << sys_err_code << "] [" << sys_err_code.message() << "].") |
Logs a warning about the (often errno -based or from a library) error code in sys_err_code . More... | |
#define | FLOW_ERROR_SYS_ERROR_LOG_FATAL() FLOW_LOG_FATAL("System error occurred: [" << sys_err_code << "] [" << sys_err_code.message() << "].") |
Logs a log::Sev::S_FATAL message about the (often errno -based or from a library) error code in sys_err_code , usually just before aborting the process or otherwise entering undefined-behavior land such as via assert(false) . More... | |
#define | FLOW_ERROR_EXEC_AND_THROW_ON_ERROR(ARG_ret_type, ARG_function_name, ...) |
Narrow-use macro that implements the error code/exception semantics expected of most public-facing Flow (and Flow-like) class method APIs. More... | |
Functions | |
template<typename Func , typename Ret > | |
bool | flow::error::exec_and_throw_on_error (const Func &func, Ret *ret, Error_code *err_code, util::String_view context) |
Helper for FLOW_ERROR_EXEC_AND_THROW_ON_ERROR() macro that does everything in the latter not needing a preprocessor. More... | |
template<typename Func > | |
bool | flow::error::exec_void_and_throw_on_error (const Func &func, Error_code *err_code, util::String_view context) |
Equivalent of exec_and_throw_on_error() for operations with void return type. More... | |
#define FLOW_ERROR_EMIT_ERROR | ( | ARG_val | ) |
Sets *err_code
to ARG_val
and logs a warning about the error using FLOW_LOG_WARNING().
An err_code
variable of type that is pointer to flow::Error_code must be declared at the point where the macro is invoked.
ARG_val | Value convertible to flow::Error_code. Reminder: Error_code is trivially/implicitly convertible from any error code set (such as errno s and boost.asio network error code set) that has been boost.system-enabled. |
#define FLOW_ERROR_EMIT_ERROR_LOG_INFO | ( | ARG_val | ) |
Identical to FLOW_ERROR_EMIT_ERROR(), but the message logged has flow::log::Sev::S_INFO severity instead of S_WARNING
.
ARG_val | See FLOW_ERROR_EMIT_ERROR(). |
#define FLOW_ERROR_EXEC_AND_THROW_ON_ERROR | ( | ARG_ret_type, | |
ARG_function_name, | |||
... | |||
) |
Narrow-use macro that implements the error code/exception semantics expected of most public-facing Flow (and Flow-like) class method APIs.
The semantics it helps implement are explained in flow::Error_code doc header. More formally, here is how to use it:
First, please read flow::Error_code doc header. Next read on:
Suppose you have an API f()
in some class C
that returns type T
and promises, in its doc header, to implement the error reporting semantics listed in the aforementioned flow::Error_code doc header. That is, if user passes in null err_code
, error would cause Run_time error(e_c)
to be thrown; if non-null, then *err_code = e_c
would be set sans exception – e_c
being the error code explaining what went wrong, such as flow::net_flow::error::Code::S_WAIT_INTERRUPTED. Then here's how to use the macro:
ARG_ret_type
would be void. The present macro does not work in that case; but at that point using the function directly is concise enough. T
is a reference type. The present macro does not work in that case.ARG_ret_type | The return type of the invoking function/method. It cannot be a reference type. In practice this would be, for example, size_t when wrapping a receive() (which returns # of bytes received or 0). |
ARG_function_name | Suppose you wanted to, via infinite recursion, call the function – from where you use this macro – and would therefore write a statement of the form return F(A1, A2, ..., err_code, ...); . ARG_function_name shall be the F part of such a hypothetical statement. Tip: Even in non-static member functions (methods), just the method name – without the class name :: part – is almost always fine. Tip: However template args typically do have to be forwarded (e.g., in template<typename T> X::f() {} you'd supply f<T> as ARG_function_name ), unless the compiler can infer them. Example: in a bool X::listen(int x, Error_code* err_code, float y) {} you'd have { return listen(x, err_code, y); } and thus ARG_function_name shall be just listen . Tip: But, if there are 2+ template args, and the compiler cannot infer them, you need to surround the x<a, b, ...> with parentheses: like: FLOW_ERROR_EXEC_AND_THROW_ON_ERROR(int, (x<a, b>), ...) . |
... | First see the premise in the doc header for ARG_function_name just above. Then the ... arg list shall be as follows: A1, A2, ..., _1, ... . In other words it shall be the arg list for the invoking function/method as-if recursively calling it, but with the err_code arg replaced by the special identifier _1 . Example: in a bool X::listen(int x, Error_code* err_code, float y) {} you'd have { return listen(x, err_code, y); } and thus ... arg list shall be: x, _1, y . |
#define FLOW_ERROR_LOG_ERROR | ( | ARG_val | ) |
Logs a warning about the given error code using FLOW_LOG_WARNING().
ARG_val | See FLOW_ERROR_EMIT_ERROR(). |
#define FLOW_ERROR_SYS_ERROR_LOG_FATAL | ( | ) | FLOW_LOG_FATAL("System error occurred: [" << sys_err_code << "] [" << sys_err_code.message() << "].") |
Logs a log::Sev::S_FATAL message about the (often errno
-based or from a library) error code in sys_err_code
, usually just before aborting the process or otherwise entering undefined-behavior land such as via assert(false)
.
sys_err_code
must be an object of type flow::Error_code in the context of the macro's invocation.
This is identical to FLOW_ERROR_SYS_ERROR_LOG_WARNING(), except the message logged has FATAL severity instead of a mere WARNING. Notes in that macro's doc header generally apply. However the use case is different.
The recommended (but in no way enforced or mandatory) pattern is something like:
#define FLOW_ERROR_SYS_ERROR_LOG_WARNING | ( | ) | FLOW_LOG_WARNING("System error occurred: [" << sys_err_code << "] [" << sys_err_code.message() << "].") |
Logs a warning about the (often errno
-based or from a library) error code in sys_err_code
.
sys_err_code
must be an object of type flow::Error_code in the context of the macro's invocation. See also FLOW_ERROR_SYS_ERROR_LOG_FATAL().
Note this implies a convention wherein system (especially errno
-based or from a libary) error codes are to be saved into a stack variable or parameter flow::Error_code sys_err_code
. Of course if you don't like this convention and/or this error message, it is trivial to log something manually.
It's a functional macro despite taking no arguments to convey that it mimics a void
free function.
The recommended (but in no way enforced or mandatory) pattern is something like: