libzypp  17.37.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 
60  std::exception_ptr do_ZYPP_FWD_EXCPT_PTR(const std::exception_ptr & excpt_r, CodeLocation &&where_r )
61  {
62  try {
63  std::rethrow_exception( excpt_r );
64  } catch ( zypp::Exception &e ) {
65  Exception::log( e, where_r, "RETHROW (FWD) EXCPTR: " );
66  e.relocate( std::move(where_r) );
67  return std::current_exception();
68  } catch ( const std::exception & e ) {
69  Exception::log( typeid(e).name(), where_r, "RETHROW (FWD) EXCPTR: " );
70  return std::current_exception();
71  } catch (...) {
72  Exception::log( "Unknown Exception", where_r, "RETHROW (FWD) EXCPTR: " );
73  return std::current_exception();
74  }
75  }
76 
77  void do_ZYPP_CAUGHT(const std::exception_ptr &excpt_r, CodeLocation &&where_r)
78  {
79  try {
80  std::rethrow_exception( excpt_r );
81  } catch ( zypp::Exception &e ) {
82  Exception::log( e, where_r, "CAUGHT: " );
83  } catch ( const std::exception & e ) {
84  Exception::log( typeid(e).name(), where_r, "CAUGHT: " );
85  } catch (...) {
86  Exception::log( "Unknown Exception", where_r, "CAUGHT: " );
87  }
88  }
89 
91  } // namespace exception_detail
93 
95  {}
96 
97  Exception::Exception( const std::string & msg_r )
98  : _msg( msg_r )
99  {}
100 
101  Exception::Exception( std::string && msg_r )
102  : _msg( std::move(msg_r) )
103  {}
104 
105  Exception::Exception( const std::string & msg_r, const Exception & history_r )
106  : _msg( msg_r )
107  { remember( history_r ); }
108 
109  Exception::Exception( std::string && msg_r, const Exception & history_r )
110  : _msg( std::move(msg_r) )
111  { remember( history_r ); }
112 
113  Exception::Exception( const std::string & msg_r, Exception && history_r )
114  : _msg( msg_r )
115  { remember( std::move(history_r) ); }
116 
117  Exception::Exception( std::string && msg_r, Exception && history_r )
118  : _msg( std::move(msg_r) )
119  { remember( std::move(history_r) ); }
120 
122  {}
123 
124  std::string Exception::asString() const
125  {
126  std::ostringstream str;
127  dumpOn( str );
128  return str.str();
129  }
130 
131  std::string Exception::asUserString() const
132  {
133  std::ostringstream str;
134  dumpOn( str );
135  // call gettext to translate the message. This will
136  // not work if dumpOn() uses composed messages.
137  return _(str.str().c_str());
138  }
139 
140  std::string Exception::asUserHistory() const
141  {
142  if ( historyEmpty() )
143  return asUserString();
144 
145  std::string ret( asUserString() );
146  if ( ret.empty() )
147  return historyAsString();
148 
149  ret += '\n';
150  ret += historyAsString();
151  return ret;
152  }
153 
154  void Exception::remember( const Exception & old_r )
155  {
156  if ( &old_r != this ) // no self-remember
157  {
158  History newh( old_r._history.begin(), old_r._history.end() );
159  newh.push_front( old_r.asUserString() );
160  _history.swap( newh );
161  }
162  }
163 
165  {
166  if ( &old_r != this ) // no self-remember
167  {
168  History & newh( old_r._history ); // stealing it
169  newh.push_front( old_r.asUserString() );
170  _history.swap( newh );
171  }
172  }
173 
174  void Exception::remember( std::exception_ptr old_r )
175  {
176  try {
177  if (old_r) {
178  std::rethrow_exception(std::move(old_r));
179  }
180  } catch( const Exception& e ) {
181  remember( e );
182  } catch ( const std::exception& e ) {
183  addHistory( e.what() );
184  } catch ( ... ) {
185  addHistory( "Remembered unknown exception" );
186  }
187  }
188 
189  void Exception::addHistory( const std::string & msg_r )
190  { _history.push_front( msg_r ); }
191 
192  void Exception::addHistory( std::string && msg_r )
193  { _history.push_front( std::move(msg_r) ); }
194 
195  std::string Exception::historyAsString() const
196  {
197  std::ostringstream ret;
198  if ( not _history.empty() ) {
199  ret << _("History:");
200  for ( const std::string & entry : _history ) {
201  strv::split( entry, "\n", [&ret]( std::string_view line_r, unsigned idx, bool last_r ) -> void {
202  if ( not ( last_r && line_r.empty() ) )
203  ret << endl << (idx==0?" - ":" ") << line_r;
204  });
205  }
206  }
207  return ret.str();
208  }
209 
210  std::ostream & Exception::dumpOn( std::ostream & str ) const
211  { return str << _msg; }
212 
213  std::ostream & Exception::dumpError( std::ostream & str ) const
214  { return dumpOn( str << _where << ": " ); }
215 
216  std::ostream & operator<<( std::ostream & str, const Exception & obj )
217  { return obj.dumpError( str ); }
218 
219  std::ostream & operator<<( std::ostream & str, const std::exception_ptr &excptPtr )
220  {
221  try {
222  std::rethrow_exception (excptPtr) ;
223  } catch ( const zypp::Exception &e ) {
224  str << e; // forward to Exception stream operator
225  } catch ( const std::exception &e ) {
226  str << "std::exception: (" << e.what() << ")";
227  } catch ( ... ) {
228  str << "Unknown exception";
229  }
230  return str;
231  }
232 
233  std::string Exception::strErrno( int errno_r )
234  { return str::strerror( errno_r ); }
235 
236  std::string Exception::strErrno( int errno_r, std::string msg_r )
237  {
238  msg_r += ": ";
239  return msg_r += strErrno( errno_r );
240  }
241 
242  void Exception::log( const Exception & excpt_r, const CodeLocation & where_r,
243  const char *const prefix_r )
244  {
245  INT << where_r << " " << prefix_r << " " << excpt_r.asUserHistory() << endl;
246  }
247 
248  void Exception::log( const char * typename_r, const CodeLocation & where_r,
249  const char *const prefix_r )
250  {
251  INT << where_r << " " << prefix_r << " exception of type " << typename_r << endl;
252  }
254 } // namespace zypp
std::exception_ptr do_ZYPP_FWD_EXCPT_PTR(const std::exception_ptr &excpt_r, CodeLocation &&where_r)
Helper for ZYPP_FWD_CURRENT_EXCPT().
Definition: Exception.cc:60
#define _(MSG)
Definition: Gettext.h:39
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:317
void do_ZYPP_CAUGHT(const std::exception_ptr &excpt_r, CodeLocation &&where_r)
Helper for std::exception_ptr.
Definition: Exception.cc:77
#define INT
Definition: Logger.h:104
virtual std::ostream & dumpOn(std::ostream &str) const
Overload this to print a proper error message.
Definition: Exception.cc:210
static std::string strErrno(int errno_r)
Make a string from errno_r.
Definition: Exception.cc:233
void addHistory(const std::string &msg_r)
Add some message text to the history.
Definition: Exception.cc:189
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:39
std::string _msg
Definition: Exception.h:318
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:154
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:242
std::string strerror(int errno_r)
Return string describing the error_r code.
Definition: String.cc:56
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:602
std::string asString() const
Error message provided by dumpOn as string.
Definition: Exception.cc:124
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Definition: Exception.cc:140
std::string asUserString() const
Translated error message as string suitable for the user.
Definition: Exception.cc:131
bool historyEmpty() const
Whether the history list is empty.
Definition: Exception.h:273
std::string historyAsString() const
The history as string.
Definition: Exception.cc:195
History _history
Definition: Exception.h:319
Exception()
Default ctor.
Definition: Exception.cc:94
Base class for Exception.
Definition: Exception.h:152
std::ostream & dumpError(std::ostream &str) const
Called by std::ostream & operator<<.
Definition: Exception.cc:213
~Exception() override
Dtor.
Definition: Exception.cc:121
Keep FILE, FUNCTION and LINE.
Definition: Exception.h:35
std::list< std::string > History
Definition: Exception.h:158
void relocate(const CodeLocation &where_r) const
Exchange location on rethrow.
Definition: Exception.h:194
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
std::string asString() const
Location as string.
Definition: Exception.cc:30