|
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 errnos 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: