Warning, file /sdk/codevis/thirdparty/soci/src/core/error.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 // 0002 // Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton 0003 // Copyright (C) 2015 Vadim Zeitlin 0004 // Distributed under the Boost Software License, Version 1.0. 0005 // (See accompanying file LICENSE_1_0.txt or copy at 0006 // http://www.boost.org/LICENSE_1_0.txt) 0007 // 0008 0009 #define SOCI_SOURCE 0010 0011 #include "soci/error.h" 0012 0013 #include <sstream> 0014 #include <vector> 0015 0016 namespace soci 0017 { 0018 0019 class soci_error_extra_info 0020 { 0021 public: 0022 soci_error_extra_info() 0023 { 0024 } 0025 0026 // Default copy ctor, assignment operator and dtor are fine. 0027 0028 char const* get_full_message(std::string const& message) 0029 { 0030 if (full_message_.empty()) 0031 { 0032 full_message_ = message; 0033 0034 if (!contexts_.empty()) 0035 { 0036 // This is a hack, but appending the extra context to the 0037 // message looks much better if we remove the full stop at its 0038 // end first. 0039 if (*full_message_.rbegin() == '.') 0040 full_message_.erase(full_message_.size() - 1); 0041 0042 // Now do append all the extra context we have. 0043 typedef std::vector<std::string>::const_iterator iter_type; 0044 for (iter_type i = contexts_.begin(); i != contexts_.end(); ++i) 0045 { 0046 full_message_ += " "; 0047 full_message_ += *i; 0048 } 0049 0050 // It seems better to always terminate the full message with a 0051 // full stop, even if the original error message didn't have it 0052 // (and if it had, we just restore the one we chopped off). 0053 full_message_ += "."; 0054 } 0055 } 0056 0057 return full_message_.c_str(); 0058 } 0059 0060 void add_context(std::string const& context) 0061 { 0062 full_message_.clear(); 0063 contexts_.push_back(context); 0064 } 0065 0066 private: 0067 // The full error message, we need to store it as a string as we return a 0068 // pointer to its contents from get_full_message(). 0069 std::string full_message_; 0070 0071 // If non-empty, contains extra context for this exception, e.g. 0072 // information about the SQL statement that resulted in it, with the top 0073 // element corresponding to the most global context. 0074 std::vector<std::string> contexts_; 0075 }; 0076 0077 namespace 0078 { 0079 0080 // Make a safe, even in presence of exceptions, heap-allocated copy of the 0081 // given object if it's non-null (otherwise just return null pointer). 0082 soci_error_extra_info *make_safe_copy(soci_error_extra_info* info) 0083 { 0084 try 0085 { 0086 return info ? new soci_error_extra_info(*info) : NULL; 0087 } 0088 catch (...) 0089 { 0090 // Copy ctor of an exception class shouldn't throw to avoid program 0091 // termination, so it's better to lose the extra information than allow 0092 // an exception to except from here. 0093 return NULL; 0094 } 0095 } 0096 0097 } // anonymous namespace 0098 0099 soci_error::soci_error(std::string const & msg) 0100 : std::runtime_error(msg) 0101 { 0102 info_ = NULL; 0103 } 0104 0105 soci_error::soci_error(soci_error const& e) noexcept 0106 : std::runtime_error(e) 0107 { 0108 info_ = make_safe_copy(e.info_); 0109 } 0110 0111 soci_error& soci_error::operator=(soci_error const& e) noexcept 0112 { 0113 if (this == &e) 0114 { 0115 return *this; 0116 } 0117 0118 std::runtime_error::operator=(e); 0119 0120 delete info_; 0121 info_ = make_safe_copy(e.info_); 0122 0123 return *this; 0124 } 0125 0126 soci_error::~soci_error() noexcept 0127 { 0128 delete info_; 0129 } 0130 0131 std::string soci_error::get_error_message() const 0132 { 0133 return std::runtime_error::what(); 0134 } 0135 0136 char const* soci_error::what() const noexcept 0137 { 0138 if (info_) 0139 return info_->get_full_message(get_error_message()); 0140 0141 return std::runtime_error::what(); 0142 } 0143 0144 void soci_error::add_context(std::string const& context) 0145 { 0146 if (!info_) 0147 info_ = new soci_error_extra_info(); 0148 0149 info_->add_context(context); 0150 } 0151 0152 } // namespace soci