Mal ausprobieren ob damit Exception einfacher in der Handhabung werden...
Aus Exceptionally Bad: The Misuse of Exceptions in C++ & How to Do Better - Peter Muldoon - CppCon 2023
Conclusion of the talk:
What should they used for ?
• Error tracing (logging)
• Stack unwinding (reset / termination)
• Data passing / Control flow (when necessary)
When should they used ?
• As “Rarely” as possible
• Serious/infrequent/unexpected errors
• With as few exception types as possible (as determined by catch functionality)
template<typename DATA_T>
class OmegaException {
public:
OmegaException(std::string str, DATA_T data, const std::source_location& loc = std::source_location::current(), std::stacktrace trace = std::stacktrace::current())
:err_str_{std::move(str)}, user_data_{std::move(data)}, location_{loc}, backtrace_{trace} { }
std::string& what() { return err_str_; }
const std::string& what() const noexcept { return err_str_; }
const std::source_location& where() const noexcept { return location_; }
const std::stacktrace& stack() const noexcept { return backtrace_; }
DATA_T& data(){ return user_data_;}
const DATA_T& data() const noexcept { return user_data_; }
private:
std::string err_str_;
DATA_T user_data_;
const std::source_location location_;
const std::stacktrace backtrace_;
}
std::ostream& operator << (std::ostream& os, const std::source_location& location) {
os << location.file_name() << "("
<< location.line() << ":"
<< location.column() << "), function `"
<< location.function_name() << "`";
return os;
}
std::ostream& operator << (std::ostream& os, const std::stacktrace& backtrace) {
for(auto iter = backtrace.begin(); iter != (backtrace.end()-3); ++iter) {
os << iter->source_file() << "(" << iter->source_line()
<< ") : " << iter->description() << "\n";
}
return os;
}
///////////////
enum Errs1 { bad = 1, real_bad };
enum class Errs2 { not_bad = 10, not_good };
using MyExceptionErrs1 = OmegaException<Errs1>;
using MyExceptionErrs2 = OmegaException<Errs2>;
throw MyExceptionErrs1(“Bad Order id", real_bad);
catch(const MyExceptionErrs1& e) {
std::cout << "Failed to process with code (" << e.data() << ") : "
<< e.what() << “\n" << e.where() << std::endl;
}
/*
Failed to process with code (2) : Bad Order id
/app/example.cpp(76:69), function `Order findOrder(unsigned int
*/
//////////////
struct bucket {
int id_;
Msg msg_;
};
using MyExceptionBucket = OmegaException< bucket >;
throw MyExceptionBucket ("bad error", bucket{cliendId, amsg});
catch(MyExceptionBucket& eb) {
std::cout << "Failed to process id (" << e.data().id_ << ") : "
<< e.what() << "\n" << e.stack() << std::endl;
send_error(eb.data().msg_);
}
/*
Failed to process id (222) : Bad Order id
example.cpp(76) : findOrder(unsigned int)
example.cpp(82) : processOrder(unsigned int)
example.cpp(97) : main
*/