C++Guns – RoboBlog

03.04.2024

OmegaException class von Peter Muldoon

Filed under: Allgemein — Tags: — Thomas @ 21:04

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
*/

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress