LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
Exception.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008-2014 LSST Corporation.
5  *
6  * This product includes software developed by the
7  * LSST Project (http://www.lsst.org/).
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the LSST License Statement and
20  * the GNU General Public License along with this program. If not,
21  * see <http://www.lsstcorp.org/LegalNotices/>.
22  */
23 
24 #ifndef __GNUC__
25 # define __attribute__(x) /*NOTHING*/
26 #endif
27 
28 #include <cstring>
29 #include <ostream>
30 #include <sstream>
31 #include <string>
32 
34 
35 namespace lsst { namespace pex { namespace exceptions {
36 
38  char const* file, int line, char const* func,
39  std::string const& message
40 ) :
41  _file(file), _line(line), _func(func), _message(message)
42 {}
43 
45  char const* file, int line, char const* func,
46  std::string const& message
47 ) : _message(message), _traceback(1, Tracepoint(file, line, func, message)) {}
48 
50  std::string const& message
51 ) : _message(message), _traceback() {}
52 
53 Exception::~Exception(void) throw() {}
54 
56  char const* file, int line, char const* func, std::string const& message
57 ) {
58  std::ostringstream stream;
59  stream << _message;
60  if (_traceback.empty()) {
61  // This means the message-only constructor was used, which should only happen
62  // from Python...but this method isn't accessible from Python, so maybe
63  // this Exception was thrown in Python, then passed back to C++. Or, more
64  // likely, someone didn't read the warning and threw this exception in C++
65  // without using LSST_EXCEPT.
66  // But, because we don't have a traceback for that first message, we can't
67  // add one here without messing up the stringification logic later. Since
68  // this is a rare case (and should be considered a bug, but we don't want
69  // exception code throwing its own exceptions unless it absolutely has to),
70  // we'll proceed by just appending the message and ignoring the traceback.
71  stream << "; " << message;
72  } else {
73  if (_traceback.size() == static_cast<std::size_t>(1)) {
74  // The original message doesn't have an index (because it's faster,
75  // and there's no need if there's only one), so when we add the second,
76  // we have to give it an index.
77  stream << " {0}; ";
78  } else {
79  stream << "; ";
80  }
81  stream << message << " {" << _traceback.size() << "}";
82  _traceback.push_back(Tracepoint(file, line, func, message));
83  }
84  _message = stream.str();
85 
86 }
87 
88 Traceback const&
89  Exception::getTraceback(void) const throw() {
90  return _traceback;
91 }
92 
93 std::ostream& Exception::addToStream(std::ostream& stream) const {
94  if (_traceback.empty()) {
95  // The exception was raised in Python, so we don't include the traceback, the type, or any
96  // newlines, because Python will print those itself.
97  stream << _message;
98  } else {
99  stream << std::endl; // Start with a newline to separate our stuff from Pythons "<type>: " prefix.
100  for (std::size_t i = 0; i != _traceback.size(); ++i) {
101  stream << " File \"" << _traceback[i]._file
102  << "\", line " << _traceback[i]._line
103  << ", in " << _traceback[i]._func << std::endl;
104  stream << " " << _traceback[i]._message << " {" << i << "}" << std::endl;
105  }
106  std::string type(getType(), 0, std::strlen(getType()) - 2);
107  stream << type << ": '" << _message << "'" << std::endl;
108  }
109  return stream;
110 }
111 
112 char const* Exception::what(void) const throw() {
113  return _message.c_str();
114 }
115 
116 char const* Exception::getType(void) const throw() {
117  return "lsst::pex::exceptions::Exception *";
118 }
119 
121  return new Exception(*this);
122 }
123 
124 std::ostream& operator<<(
125  std::ostream& stream, Exception const& e) {
126  return e.addToStream(stream);
127 }
128 
129 }}} // namespace lsst::pex::exceptions
virtual char const * getType(void) const
Definition: Exception.cc:116
std::vector< Tracepoint > Traceback
Definition: Exception.h:97
void addMessage(char const *file, int line, char const *func, std::string const &message)
Definition: Exception.cc:55
virtual char const * what(void) const
Definition: Exception.cc:112
virtual std::ostream & addToStream(std::ostream &stream) const
Definition: Exception.cc:93
Tracepoint(char const *file, int line, char const *func, std::string const &message)
Definition: Exception.cc:37
std::ostream & operator<<(std::ostream &stream, Exception const &e)
Definition: Exception.cc:124
Exception(char const *file, int line, char const *func, std::string const &message)
Definition: Exception.cc:44
Traceback const & getTraceback(void) const
Retrieve the list of tracepoints associated with an exception.
Definition: Exception.cc:89
One point in the Traceback vector held by Exception.
Definition: Exception.h:80
virtual Exception * clone(void) const
Definition: Exception.cc:120