libzypp  17.14.0
Exception.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #ifndef ZYPP_BASE_EXCEPTION_H
13 #define ZYPP_BASE_EXCEPTION_H
14 
15 #include <iosfwd>
16 #include <string>
17 #include <list>
18 #include <stdexcept>
19 #include <typeinfo>
20 #include <type_traits>
21 
22 #include "zypp/base/Errno.h"
23 
25 namespace zypp
26 {
27 
28  namespace exception_detail
29  {
30 
34  struct CodeLocation
35  {
36  friend std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
37 
40  : _line( 0 )
41  {}
42 
44  CodeLocation( const std::string & file_r,
45  const std::string & func_r,
46  unsigned line_r )
47  : _file( file_r ), _func( func_r ), _line( line_r )
48  {}
49 
51  std::string asString() const;
52 
53  private:
54  std::string _file;
55  std::string _func;
56  unsigned _line;
57  };
59 
61  //#define ZYPP_EX_CODELOCATION ::zypp::exception_detail::CodeLocation(__FILE__,__FUNCTION__,__LINE__)
62 #define ZYPP_EX_CODELOCATION ::zypp::exception_detail::CodeLocation(( *__FILE__ == '/' ? strrchr( __FILE__, '/' ) + 1 : __FILE__ ),__FUNCTION__,__LINE__)
63 
65  std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
66 
68  } // namespace exception_detail
70 
72  //
73  // CLASS NAME : Exception
145  class Exception : public std::exception
146  {
147  friend std::ostream & operator<<( std::ostream & str, const Exception & obj );
148 
149  public:
151  typedef std::list<std::string> History;
152  typedef History::const_iterator HistoryIterator;
154 
158  Exception();
159 
163  Exception( const std::string & msg_r );
165  Exception( std::string && msg_r );
166 
171  Exception( const std::string & msg_r, const Exception & history_r );
173  Exception( std::string && msg_r, const Exception & history_r );
175  Exception( const std::string & msg_r, Exception && history_r );
177  Exception( std::string && msg_r, Exception && history_r );
178 
180  virtual ~Exception() throw();
181 
183  const CodeLocation & where() const
184  { return _where; }
185 
187  void relocate( const CodeLocation & where_r ) const
188  { _where = where_r; }
189 
195  const std::string & msg() const
196  { return _msg; }
197 
199  std::string asString() const;
200 
204  std::string asUserString() const;
205 
206  public:
214 
216  void remember( const Exception & old_r );
218  void remember( Exception && old_r );
219 
221  void addHistory( const std::string & msg_r );
223  void addHistory( std::string && msg_r );
224 
226  template<class TContainer>
227  void addToHistory( const TContainer & msgc_r )
228  {
229  for ( const std::string & el : msgc_r )
230  addHistory( el );
231  }
233  template<class TContainer>
234  void moveToHistory( TContainer && msgc_r )
235  {
236  for ( std::string & el : msgc_r )
237  addHistory( std::move(el) );
238  }
239 
242  { return _history.begin(); }
243 
246  { return _history.end(); }
247 
249  bool historyEmpty() const
250  { return _history.empty(); }
251 
254  { return _history.size(); }
255 
266  std::string historyAsString() const;
267 
269  std::string asUserHistory() const;
271 
272  protected:
273 
275  virtual std::ostream & dumpOn( std::ostream & str ) const;
276 
277  public:
279  static std::string strErrno( int errno_r );
281  static std::string strErrno( int errno_r, const std::string & msg_r );
283  static std::string strErrno( int errno_r, std::string && msg_r );
284 
285  public:
289  static void log( const Exception & excpt_r, const CodeLocation & where_r,
290  const char *const prefix_r );
292  static void log( const char * typename_r, const CodeLocation & where_r,
293  const char *const prefix_r );
294  private:
296  std::string _msg;
298 
300  virtual const char * what() const throw()
301  { return _msg.c_str(); }
302 
307  std::ostream & dumpError( std::ostream & str ) const;
308  };
310 
312  std::ostream & operator<<( std::ostream & str, const Exception & obj );
313 
315  namespace exception_detail
316  {
318  template<class TExcpt>
319  using EnableIfIsException = typename std::enable_if< std::is_base_of<Exception,TExcpt>::value, int>::type;
320 
322  template<class TExcpt>
323  using EnableIfNotException = typename std::enable_if< !std::is_base_of<Exception,TExcpt>::value, int>::type;
324 
325 
327  template<class TExcpt, EnableIfIsException<TExcpt> = 0>
328  void do_ZYPP_THROW( const TExcpt & excpt_r, const CodeLocation & where_r ) __attribute__((noreturn));
329  template<class TExcpt, EnableIfIsException<TExcpt>>
330  void do_ZYPP_THROW( const TExcpt & excpt_r, const CodeLocation & where_r )
331  {
332  excpt_r.relocate( where_r );
333  Exception::log( excpt_r, where_r, "THROW: " );
334  throw( excpt_r );
335  }
336 
338  template<class TExcpt, EnableIfNotException<TExcpt> = 0>
339  void do_ZYPP_THROW( const TExcpt & excpt_r, const CodeLocation & where_r ) __attribute__((noreturn));
340  template<class TExcpt, EnableIfNotException<TExcpt>>
341  void do_ZYPP_THROW( const TExcpt & excpt_r, const CodeLocation & where_r )
342  {
343  Exception::log( typeid(excpt_r).name(), where_r, "THROW: " );
344  throw( excpt_r );
345  }
346 
347 
349  template<class TExcpt, EnableIfIsException<TExcpt> = 0>
350  void do_ZYPP_CAUGHT( const TExcpt & excpt_r, const CodeLocation & where_r )
351  {
352  Exception::log( excpt_r, where_r, "CAUGHT: " );
353  }
354 
356  template<class TExcpt, EnableIfNotException<TExcpt> = 0>
357  void do_ZYPP_CAUGHT( const TExcpt & excpt_r, const CodeLocation & where_r )
358  {
359  Exception::log( typeid(excpt_r).name(), where_r, "CAUGHT: " );
360  }
361 
362 
364  template<class TExcpt, EnableIfIsException<TExcpt> = 0>
365  void do_ZYPP_RETHROW( const TExcpt & excpt_r, const CodeLocation & where_r ) __attribute__((noreturn));
366  template<class TExcpt, EnableIfIsException<TExcpt>>
367  void do_ZYPP_RETHROW( const TExcpt & excpt_r, const CodeLocation & where_r )
368  {
369  Exception::log( excpt_r, where_r, "RETHROW: " );
370  excpt_r.relocate( where_r );
371  throw;
372  }
373 
375  template<class TExcpt, EnableIfNotException<TExcpt> = 0>
376  void do_ZYPP_RETHROW( const TExcpt & excpt_r, const CodeLocation & where_r ) __attribute__((noreturn));
377  template<class TExcpt, EnableIfNotException<TExcpt>>
378  void do_ZYPP_RETHROW( const TExcpt & excpt_r, const CodeLocation & where_r )
379  {
380  Exception::log( excpt_r, where_r, "RETHROW: " );
381  throw;
382  }
383  } // namespace exception_detail
385 
392 #define ZYPP_THROW(EXCPT)\
393  ::zypp::exception_detail::do_ZYPP_THROW( EXCPT, ZYPP_EX_CODELOCATION )
394 
396 #define ZYPP_CAUGHT(EXCPT)\
397  ::zypp::exception_detail::do_ZYPP_CAUGHT( EXCPT, ZYPP_EX_CODELOCATION )
398 
400 #define ZYPP_RETHROW(EXCPT)\
401  ::zypp::exception_detail::do_ZYPP_RETHROW( EXCPT, ZYPP_EX_CODELOCATION )
402 
403 
405 #define ZYPP_THROW_MSG(EXCPTTYPE, MSG)\
406  ZYPP_THROW( EXCPTTYPE( MSG ) )
407 
409 #define ZYPP_THROW_ERRNO(EXCPTTYPE)\
410  ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno) ) )
411 
413 #define ZYPP_THROW_ERRNO1(EXCPTTYPE, ERRNO)\
414  ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO) ) )
415 
417 #define ZYPP_THROW_ERRNO_MSG(EXCPTTYPE, MSG)\
418  ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno,MSG) ) )
419 
421 #define ZYPP_THROW_ERRNO_MSG1(EXCPTTYPE, ERRNO,MSG)\
422  ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO,MSG) ) )
423 
424 
426 } // namespace zypp
428 #endif // ZYPP_BASE_EXCEPTION_H