libzypp  17.32.5
Exception.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <sstream>
14 
15 #include <zypp-core/base/Logger.h>
17 #include <zypp-core/base/Gettext.h>
18 #include <zypp-core/base/StringV.h>
20 
21 using std::endl;
22 
24 namespace zypp
25 {
26  namespace exception_detail
28  {
29 
30  std::string CodeLocation::asString() const
31  {
32  return str::form( "%s(%s):%u",
33  _file.c_str(),
34  _func.c_str(),
35  _line );
36  }
37 
38  std::ostream & operator<<( std::ostream & str, const CodeLocation & obj )
39  { return str << obj.asString(); }
40 
41  void do_ZYPP_RETHROW(const std::exception_ptr &excpt_r, const CodeLocation &where_r)
42  {
43  if ( !excpt_r )
44  return;
45 
46  try {
47  std::rethrow_exception (excpt_r);
48  } catch ( const zypp::Exception &e ) {
49  Exception::log( e, where_r, "RETHROW: " );
50  throw;
51  } catch ( const std::exception & e ) {
52  Exception::log( typeid(e).name(), where_r, "RETHROW: " );
53  throw;
54  } catch (...) {
55  Exception::log( "Unknown Exception", where_r, "RETHROW: " );
56  throw;
57  }
58  }
59 
61  } // namespace exception_detail
63 
65  {}
66 
67  Exception::Exception( const std::string & msg_r )
68  : _msg( msg_r )
69  {}
70 
71  Exception::Exception( std::string && msg_r )
72  : _msg( std::move(msg_r) )
73  {}
74 
75  Exception::Exception( const std::string & msg_r, const Exception & history_r )
76  : _msg( msg_r )
77  { remember( history_r ); }
78 
79  Exception::Exception( std::string && msg_r, const Exception & history_r )
80  : _msg( std::move(msg_r) )
81  { remember( history_r ); }
82 
83  Exception::Exception( const std::string & msg_r, Exception && history_r )
84  : _msg( msg_r )
85  { remember( std::move(history_r) ); }
86 
87  Exception::Exception( std::string && msg_r, Exception && history_r )
88  : _msg( std::move(msg_r) )
89  { remember( std::move(history_r) ); }
90 
92  {}
93 
94  std::string Exception::asString() const
95  {
96  std::ostringstream str;
97  dumpOn( str );
98  return str.str();
99  }
100 
101  std::string Exception::asUserString() const
102  {
103  std::ostringstream str;
104  dumpOn( str );
105  // call gettext to translate the message. This will
106  // not work if dumpOn() uses composed messages.
107  return _(str.str().c_str());
108  }
109 
110  std::string Exception::asUserHistory() const
111  {
112  if ( historyEmpty() )
113  return asUserString();
114 
115  std::string ret( asUserString() );
116  if ( ret.empty() )
117  return historyAsString();
118 
119  ret += '\n';
120  ret += historyAsString();
121  return ret;
122  }
123 
124  void Exception::remember( const Exception & old_r )
125  {
126  if ( &old_r != this ) // no self-remember
127  {
128  History newh( old_r._history.begin(), old_r._history.end() );
129  newh.push_front( old_r.asUserString() );
130  _history.swap( newh );
131  }
132  }
133 
135  {
136  if ( &old_r != this ) // no self-remember
137  {
138  History & newh( old_r._history ); // stealing it
139  newh.push_front( old_r.asUserString() );
140  _history.swap( newh );
141  }
142  }
143 
144  void Exception::remember( std::exception_ptr old_r )
145  {
146  try {
147  if (old_r) {
148  std::rethrow_exception(std::move(old_r));
149  }
150  } catch( const Exception& e ) {
151  remember( e );
152  } catch ( const std::exception& e ) {
153  addHistory( e.what() );
154  } catch ( ... ) {
155  addHistory( "Remembered unknown exception" );
156  }
157  }
158 
159  void Exception::addHistory( const std::string & msg_r )
160  { _history.push_front( msg_r ); }
161 
162  void Exception::addHistory( std::string && msg_r )
163  { _history.push_front( std::move(msg_r) ); }
164 
165  std::string Exception::historyAsString() const
166  {
167  std::ostringstream ret;
168  if ( not _history.empty() ) {
169  ret << _("History:") << endl;
170  for ( const std::string & entry : _history ) {
171  strv::split( entry, "\n", [&ret]( std::string_view line_r, unsigned idx, bool last_r ) -> void {
172  if ( not ( last_r && line_r.empty() ) )
173  ret << (idx==0?" - ":" ") << line_r << endl;
174  });
175  }
176  }
177  return ret.str();
178  }
179 
180  std::ostream & Exception::dumpOn( std::ostream & str ) const
181  { return str << _msg; }
182 
183  std::ostream & Exception::dumpError( std::ostream & str ) const
184  { return dumpOn( str << _where << ": " ); }
185 
186  std::ostream & operator<<( std::ostream & str, const Exception & obj )
187  { return obj.dumpError( str ); }
188 
189 
190  std::string Exception::strErrno( int errno_r )
191  { return str::strerror( errno_r ); }
192 
193  std::string Exception::strErrno( int errno_r, std::string msg_r )
194  {
195  msg_r += ": ";
196  return msg_r += strErrno( errno_r );
197  }
198 
199  void Exception::log( const Exception & excpt_r, const CodeLocation & where_r,
200  const char *const prefix_r )
201  {
202  INT << where_r << " " << prefix_r << " " << excpt_r.asUserHistory() << endl;
203  }
204 
205  void Exception::log( const char * typename_r, const CodeLocation & where_r,
206  const char *const prefix_r )
207  {
208  INT << where_r << " " << prefix_r << " exception of type " << typename_r << endl;
209  }
211 } // namespace zypp
#define _(MSG)
Definition: Gettext.h:37
void do_ZYPP_RETHROW(const std::exception_ptr &excpt_r, const CodeLocation &where_r)
Definition: Exception.cc:41
std::ostream & operator<<(std::ostream &str, const CodeLocation &obj)
Definition: Exception.cc:38
CodeLocation _where
Definition: Exception.h:307
#define INT
Definition: Logger.h:100
virtual std::ostream & dumpOn(std::ostream &str) const
Overload this to print a proper error message.
Definition: Exception.cc:180
static std::string strErrno(int errno_r)
Make a string from errno_r.
Definition: Exception.cc:190
void addHistory(const std::string &msg_r)
Add some message text to the history.
Definition: Exception.cc:159
String related utilities and Regular expression matching.
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
Definition: SerialNumber.cc:52
Definition: Arch.h:363
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:37
std::string _msg
Definition: Exception.h:308
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:124
static void log(const Exception &excpt_r, const CodeLocation &where_r, const char *const prefix_r)
Drop a logline on throw, catch or rethrow.
Definition: Exception.cc:199
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \, const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition: String.h:531
std::string asString() const
Error message provided by dumpOn as string.
Definition: Exception.cc:94
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Definition: Exception.cc:110
std::string asUserString() const
Translated error message as string suitable for the user.
Definition: Exception.cc:101
bool historyEmpty() const
Whether the history list is empty.
Definition: Exception.h:263
std::string historyAsString() const
The history as string.
Definition: Exception.cc:165
History _history
Definition: Exception.h:309
Exception()
Default ctor.
Definition: Exception.cc:64
Base class for Exception.
Definition: Exception.h:146
std::ostream & dumpError(std::ostream &str) const
Called by std::ostream & operator<<.
Definition: Exception.cc:183
~Exception() override
Dtor.
Definition: Exception.cc:91
Keep FILE, FUNCTION and LINE.
Definition: Exception.h:35
std::list< std::string > History
Definition: Exception.h:152
std::string strerror(int errno_r)
Return string describing the error_r code.
Definition: String.cc:54
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
std::string asString() const
Location as string.
Definition: Exception.cc:30