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