diff --git a/include/libdnf5/common/exception.hpp b/include/libdnf5/common/exception.hpp index 0e541e1f3b..c13ef93d4d 100644 --- a/include/libdnf5/common/exception.hpp +++ b/include/libdnf5/common/exception.hpp @@ -27,6 +27,7 @@ along with libdnf. If not, see . #include #include +#include #define LIBDNF_LOCATION \ { __FILE__, __LINE__, __PRETTY_FUNCTION__ } @@ -122,6 +123,20 @@ class UserAssertionError : public std::logic_error { }; +// The exception stores the passed arguments and uses them in the catch phase. +// The problem is that the value to which the saved argument points may no longer be in memory - +// is destroyed when the program leaves the scope of the variable with the value. +// A safer solution than passing a pointer to text is to use "std::string" and pass it by value. +// +// "Concept" defines safe types that can be passed by value as arguments to the "libdnf5::Error" +// and "libdnf5::SystemError" exception constructors. +// Pointers to void are allowed because they are not dereferenced, but their value is printed. +template +concept AllowedErrorArgTypes = + std::is_arithmetic_v || std::is_base_of_v || std::is_null_pointer_v || + std::is_same_v || std::is_same_v; + + /// Base class for libdnf exceptions. Virtual methods `get_name()` and /// `get_domain_name()` should always return the exception's class name and its /// namespace (including enclosing class names in case the exception is nested in @@ -132,7 +147,7 @@ class Error : public std::runtime_error { /// /// @param format The format string for the message. /// @param args The format arguments. - template + template explicit Error(BgettextMessage format, Args... args) : std::runtime_error(b_gettextmsg_get_id(format)), format(format), @@ -172,7 +187,7 @@ class SystemError : public Error { /// @param error_code The `errno` of the error. /// @param format The format string for the message. /// @param args The format arguments. - template + template explicit SystemError(int error_code, BgettextMessage format, Args... args) : Error(format, std::forward(args)...), error_code(error_code),