iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Exceptions.H
Go to the documentation of this file.
1 /*! @file
2  @author Laurent Itti
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 #ifndef INCLUDE_NRT_CORE_BLACKBOARD_EXCEPTIONS_H
37 #define INCLUDE_NRT_CORE_BLACKBOARD_EXCEPTIONS_H
38 
40 #include <nrt/External/cereal/types/string.hpp>
41 #include <nrt/External/cereal/types/vector.hpp>
42 #include <nrt/External/cereal/types/map.hpp>
43 
44 namespace nrt
45 {
46  class ModuleBase;
47  namespace blackboard
48  {
49  //! Helper function to internally catch and rethrow exceptions within the Blackboard
50  void catchAndRethrow(std::string const & bbwhere, nrt::ModuleBase * mod);
51  };
52 
53  namespace exception
54  {
55  // ######################################################################
56  /*! \defgroup bbexceptions Blackboard-related exceptions
57 
58  Exceptions are used to indicate errors during operation of the distributed Blackboard federation, such as errors
59  occurring during execution of subscriber callbacks, errors due to some blackboards going down, etc.
60 
61  \ingroup blackboard */
62 
63  /*! @{ */ // **********************************************************************
64 
65 
66  // ######################################################################
67  //! Class for Blackboard exceptions
69  {
70  public:
71  //! Type of Blackboard error
72  /*! \note NRT programmers: if you add a type here, be sure to also update the definition of errorString() in
73  Exceptions.C */
74  enum ErrorType
75  {
76  //! Unknown Blackboard error
77  Unknown = 0,
78 
79  //! Internal Inconsistency, severe, e.g., missing keys or entries in our internal tables
81 
82  //! Unknown message type, e.g., some posted message has a type we don't know about, message was lost
83  /*! This may just mean that we received a message because we used to have a subscriber for it, but by the time
84  the message arrives that subscriber is gone. It is not a severe inconsistency in the Blackboard but this
85  exception signals that the message was lost. */
87 
88  //! We don't know this MessagePoster
89  /*! This may be thrown if trying to set the namespace or topic of an unknown MessagePoster. */
91 
92  //! We don't know this MessageChecker
93  /*! This may be thrown if trying to set the namespace or topic filter of an unknown MessageChecker. It may
94  also be thrown if we have no checker key for an incoming remote check() request. Our corresponding poster(s)
95  may have recently disappeared. This exception signals that the remote check() request will be ignored. */
97 
98  //! We don't know this MessageSubscriber
99  /*! This may be thrown if trying to set the namespace or topic filter of an unknown MessageSubscriber. It may
100  also be thrown if we have no subscriber for an incoming remotely posted message, while the remote poster
101  thought we had one. The subscriber may have recently disappeared. This exception signals that the
102  subscriber's callback will not be called although the caller expects it to be. */
104 
105  //! Suspended Blackboard (not running) refused to serve a post(), posted message was ignored and lost
107 
108  //! Something went wrong during serialization/deserialization of a message
110 
111  //! Network error when communicating with a remote Blackboard or in setting up communications with master
113 
114  //! Propagated error, an error was caught and is being propagated with more info about who caught it
116 
117  //! Malformed Topic Filter or Topic, caused std::regex to throw
119 
120  //! Module could not be found (e.g., when trying to set a module's namespace)
122 
123  //! The given Namespace string was bad (either missing a link, or otherwise malformed)
125 
126  //! A poster, subscription, or checker port is not associated with a module
127  NotModule = 13,
128 
129  //! Some operation only supported by master Blackboard was attempted on a non-master
131 
132  //! Attempted to have two different blackboards with the same nickname, or to use an otherwise phony nick
134 
135  //! Error occurred while trying to serialize/deserialize an exception
137 
138  //! Attempted to split a port that cannot be split (has an atomic message, or non-void return type)
140 
141  //! Attempted to cast an nrt::AnyMessage to something else than the actual contained message type
143 
144  //! Attempted to set topic/filter on a connector we don't know
146 
147  //! Attempted to load a module with wrong version
149 
150  //! HTTPBridge error
152 
153  //! Unknown blackboard uid or nick
155 
156  //! Duplicate instance name
158  };
159 
160  //! Data stored about an exception, we have a vector of those to simulate a stack unwinding
162  {
163  public:
164  ErrorType error;
165  std::string bbnickuid;
166  std::string where;
167  std::string what;
168 
169  //! Serialization
170  template <class Archive> void serialize(Archive & ar)
171  { ar(error, bbnickuid, where, what); }
172  };
173 
174  //! Construct from nothing, needed by serialization but contains no valid data
175  BlackboardException() throw();
176 
177  //! Standard constructor
178  BlackboardException(ErrorType const et, std::string const & wherestr, std::string const & whatstr) throw();
179 
180  //! Copy constructor
181  BlackboardException(BlackboardException const & e) throw();
182 
183  //! Destructor
184  virtual ~BlackboardException() throw();
185 
186  //! Assignment
187  BlackboardException & operator=(BlackboardException const & e) throw();
188 
189  //! Get stack trace
190  std::vector<BlackboardExceptionData> const & fulldata() const;
191 
192  //! Dump some informational description to string, full stack trace
193  std::string const str() const;
194 
195  //! Convert ErrorType to string
196  char const * errorString(ErrorType const et) const;
197 
198  protected:
199  friend void nrt::blackboard::catchAndRethrow(std::string const & bbwhere, nrt::ModuleBase * mod);
200 
201  //! Add more data, catchAndRethrow() does it
202  void adddata(BlackboardExceptionData const & d);
203 
204  friend class cereal::access;
205 
206  //! Our accumulated data
208 
209  //! Serialize object into/out of an archive
210  template <class Archive> void serialize(Archive & ar)
211  { ar(cereal::base_class<SerializableException>(this), data); }
212  };
213 
214  // ######################################################################
215  //! Class for Module exceptions
216  /*! Typically, you should throw an exception in a Module like so:
217 @code
218 throw NRT_MODULE_EXCEPTION("Oh no, something went wrong");
219 @endcode */
221  {
222  public:
223  //! Data stored about an exception, we have a vector of those to simulate a stack unwinding
225  {
226  public:
227  std::string bbnickuid; //!< The blackboard uid
228  std::string modnickuid; //!< The module uid
229  std::string where; //!< Where the exception occured
230  std::string what; //!< What caused the exception
231 
232  //! Serialization
233  template <class Archive> void serialize(Archive & ar)
234  {
235  ar( bbnickuid, modnickuid, where, what );
236  }
237  };
238 
239  //! Construct from nothing, needed by serialization but contains no valid data
240  ModuleException() throw();
241 
242  //! Construct for the first time, from within a module
243  ModuleException(nrt::ModuleBase const * mod, std::string const & wherestr, std::string const & whatstr) throw();
244 
245  //! Copy constructor
246  ModuleException(ModuleException const & e) throw();
247 
248  //! Destructor
249  virtual ~ModuleException() throw();
250 
251  //! Assignment
252  ModuleException & operator=(ModuleException const & e) throw();
253 
254  //! Get stack trace
255  std::vector<ModuleExceptionData> const & fulldata() const;
256 
257  //! Dump some informational description to string, full stack trace
258  std::string const str() const;
259 
260  //! Public data available for users to stuff whatever they like into
261  std::map<std::string, std::string> userdata;
262 
263  protected:
264  friend void nrt::blackboard::catchAndRethrow(std::string const & bbwhere, nrt::ModuleBase * mod);
265 
266  //! Add more data, catchAndRethrow() does it
267  void adddata(ModuleExceptionData const & d);
268 
269  //! Our accumulated data
270  std::vector<ModuleExceptionData> data;
271 
272  friend class cereal::access;
273 
274  //! Serialize object into/out of an archive
275  template <class Archive> void serialize(Archive & ar)
276  { ar(cereal::base_class<SerializableException>(this), data); }
277  };
278 
279 //! Macro to conveniently construct a new ModuleException using only a message
280 /*! \def NRT_MODULE_EXCEPTION(what)
281  \hideinitializer
282 
283  If you don't want to create your own specialized exception type, but still want to throw something in your Module,
284  feel free to use this convenience macro like so:
285 
286  @code
287  if (someAwfulCondition == true) throw NRT_MODULE_EXCEPTION("Some awful condition was true!");
288  @endcode */
289 #define NRT_MODULE_EXCEPTION(what) \
290  nrt::exception::ModuleException(this, \
291  std::string(__FILE__) + ":" + std::string(__PRETTY_FUNCTION__),\
292  what)
293 
294  /*! @} */ // **********************************************************************
295 
296  } // namespace exception
297 
298 } // namespace nrt
299 
300 
301 #endif // INCLUDE_NRT_CORE_BLACKBOARD_EXCEPTIONS_H