Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:48:01

0001 
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 
0004 namespace cms {
0005 
0006   Exception::Exception(std::string const& aCategory)
0007       : std::exception(), ost_(), category_(aCategory), what_(), context_(), additionalInfo_(), alreadyPrinted_(false) {}
0008 
0009   Exception::Exception(char const* aCategory)
0010       : std::exception(),
0011         ost_(),
0012         category_(std::string(aCategory)),
0013         what_(),
0014         context_(),
0015         additionalInfo_(),
0016         alreadyPrinted_(false) {}
0017 
0018   Exception::Exception(std::string const& aCategory, std::string const& message)
0019       : std::exception(), ost_(), category_(aCategory), what_(), context_(), additionalInfo_(), alreadyPrinted_(false) {
0020     init(message);
0021   }
0022 
0023   Exception::Exception(char const* aCategory, std::string const& message)
0024       : std::exception(),
0025         ost_(),
0026         category_(std::string(aCategory)),
0027         what_(),
0028         context_(),
0029         additionalInfo_(),
0030         alreadyPrinted_(false) {
0031     init(message);
0032   }
0033 
0034   Exception::Exception(std::string const& aCategory, char const* message)
0035       : std::exception(), ost_(), category_(aCategory), what_(), context_(), additionalInfo_(), alreadyPrinted_(false) {
0036     init(std::string(message));
0037   }
0038 
0039   Exception::Exception(char const* aCategory, char const* message)
0040       : std::exception(),
0041         ost_(),
0042         category_(std::string(aCategory)),
0043         what_(),
0044         context_(),
0045         additionalInfo_(),
0046         alreadyPrinted_(false) {
0047     init(std::string(message));
0048   }
0049 
0050   void Exception::init(std::string const& message) {
0051     ost_ << message;
0052     if (!message.empty()) {
0053       unsigned sz = message.size() - 1;
0054       if (message[sz] != '\n' && message[sz] != ' ')
0055         ost_ << " ";
0056     }
0057   }
0058 
0059   Exception::Exception(std::string const& aCategory, std::string const& message, Exception const& another)
0060       : std::exception(),
0061         ost_(),
0062         category_(aCategory),
0063         what_(),
0064         context_(another.context()),
0065         additionalInfo_(another.additionalInfo()),
0066         alreadyPrinted_(false) {
0067     ost_ << message;
0068     // check for newline at end of message first
0069     if (!message.empty() && message[message.size() - 1] != '\n') {
0070       ost_ << "\n";
0071     }
0072     append(another);
0073   }
0074 
0075   Exception::Exception(Exception const& other)
0076       : std::exception(),
0077         ost_(),
0078         category_(other.category_),
0079         what_(other.what_),
0080         context_(other.context_),
0081         additionalInfo_(other.additionalInfo_),
0082         alreadyPrinted_(other.alreadyPrinted_.load()) {
0083     ost_ << other.ost_.str();
0084   }
0085 
0086   Exception::~Exception() noexcept {}
0087 
0088   void Exception::swap(Exception& other) {
0089     ost_ << other.ost_.str();
0090     category_.swap(other.category_);
0091     what_.swap(other.what_);
0092     context_.swap(other.context_);
0093     additionalInfo_.swap(other.additionalInfo_);
0094     // It is not possible to atomically swap atomics
0095     // This should be good enough for current use cases.
0096     bool temp = alreadyPrinted_.load();
0097     alreadyPrinted_ = other.alreadyPrinted_.load();
0098     other.alreadyPrinted_ = temp;
0099   }
0100 
0101   Exception& Exception::operator=(Exception const& other) {
0102     Exception temp(other);
0103     this->swap(temp);
0104     return *this;
0105   }
0106 
0107   char const* Exception::what() const noexcept {
0108     what_ = explainSelf();
0109     return what_.c_str();
0110   }
0111 
0112   std::string Exception::explainSelf() const {
0113     std::ostringstream ost;
0114 
0115     if (context_.empty()) {
0116       ost << "An exception of category '" << category_ << "' occurred.\n";
0117     } else {
0118       ost << "An exception of category '" << category_ << "' occurred while\n";
0119       int count = 0;
0120       for (std::list<std::string>::const_reverse_iterator i = context_.rbegin(), iEnd = context_.rend(); i != iEnd;
0121            ++i, ++count) {
0122         ost << "   [" << count << "] " << *i << "\n";
0123       }
0124     }
0125 
0126     std::string centralMessage(ost_.str());
0127     if (!centralMessage.empty()) {
0128       ost << "Exception Message:\n";
0129       ost << centralMessage;
0130       if (centralMessage[centralMessage.size() - 1] != '\n') {
0131         ost << "\n";
0132       }
0133     }
0134 
0135     if (!additionalInfo_.empty()) {
0136       ost << "   Additional Info:\n";
0137       char c = 'a';
0138       for (std::list<std::string>::const_reverse_iterator i = additionalInfo_.rbegin(), iEnd = additionalInfo_.rend();
0139            i != iEnd;
0140            ++i, ++c) {
0141         ost << "      [" << c << "] " << *i << "\n";
0142       }
0143     }
0144     return ost.str();
0145   }
0146 
0147   std::string const& Exception::category() const { return category_; }
0148 
0149   std::string Exception::message() const { return ost_.str(); }
0150 
0151   std::list<std::string> const& Exception::context() const { return context_; }
0152 
0153   std::list<std::string> const& Exception::additionalInfo() const { return additionalInfo_; }
0154 
0155   int Exception::returnCode() const { return returnCode_(); }
0156 
0157   void Exception::append(Exception const& another) { ost_ << another.message(); }
0158 
0159   void Exception::append(std::string const& more_information) { ost_ << more_information; }
0160 
0161   void Exception::append(char const* more_information) { ost_ << more_information; }
0162 
0163   void Exception::clearMessage() { ost_.str(""); }
0164 
0165   void Exception::clearContext() { context_.clear(); }
0166 
0167   void Exception::clearAdditionalInfo() { additionalInfo_.clear(); }
0168 
0169   void Exception::addContext(std::string const& context) { context_.push_back(context); }
0170 
0171   void Exception::addContext(char const* context) { context_.push_back(std::string(context)); }
0172 
0173   void Exception::addAdditionalInfo(std::string const& info) { additionalInfo_.push_back(info); }
0174 
0175   void Exception::addAdditionalInfo(char const* info) { additionalInfo_.push_back(std::string(info)); }
0176 
0177   void Exception::setContext(std::list<std::string> const& context) { context_ = context; }
0178 
0179   void Exception::setAdditionalInfo(std::list<std::string> const& info) { additionalInfo_ = info; }
0180 
0181   bool Exception::alreadyPrinted() const { return alreadyPrinted_.load(); }
0182 
0183   void Exception::setAlreadyPrinted() { alreadyPrinted_.exchange(true); }
0184 
0185   Exception* Exception::clone() const { return new Exception(*this); }
0186 
0187   void Exception::rethrow() { throw *this; }
0188 
0189   int Exception::returnCode_() const { return 8001; }
0190 
0191   std::list<std::string> Exception::history() const {
0192     std::list<std::string> returnValue;
0193     returnValue.push_back(category_);
0194     return returnValue;
0195   }
0196 }  // namespace cms