همان طور که می دونید هر کتابخانه ای که پیاده سازی می کنیم ممکنه دهها نوع exception توی آنها تعریف بشه .در واقع کلاس های استثنا باید به گونه ای تعریف کنیم که علاوه بر محتوای استک شامل اطلاعات خوبی برای logger هم داشته باشه . توی کتابخانه ها کلیه استثنا ها از کلاس FooException مشتق می شوند.که به صورت زیر تعریف شده است:
class FooException : public std::exception {
public:
FooException (const std::string& message, const std::source_location& loc = std::source_location::current(), std::error_code ec = std::error_code())
: std::exception(message.c_str()),
ec_{ec},
loc_{ loc }{
}
std::error_code ec() const {
return ec_;
}
std::source_location loc() const {
return loc_;
}
std::string get_message() const {
return std::string("File error at ") + loc_.file_name() + ":"
+ std::to_string(loc_.line()) + ": " + ec_.message();
}
private:
std::error_code ec_;
std::source_location loc_;
};
اگر مجموعه ای از استثنا ها در یک گروه قرار می گیرند بهتر است برای این گروه کلاس پایه ای مشتق شده از کلاس FooException تعریف شود و سایر اعضای گروه از این کلاس مشتق شوند.
.به طورمثال کلاس FileFooException به عنوان کلاس والد کلیه استثناهای مربوط به فایل است این کلاس باید به گونه ای تعریف شود که نام فایلی که باعث شده تا استثنا رخ دهد را در خود نگهداری کند.
class FileFooException : public FooException {
public:
FileFooException (std::string filename,const std::string& message, std::source_location loc = std::source_location::current(), std::error_code ec = std::error_code())
: FooException (message, loc , ec),
filename_{filename}
{
}
const char* filename() const {
return filename_.c_str();
}
private:
std::string filename_;
};