libzypp 17.37.17
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
20
21using std::endl;
22
24namespace zypp
25{
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
92
93
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 }
253
254} // namespace zypp
Base class for Exception.
Definition Exception.h:153
std::string _msg
Definition Exception.h:318
static std::string strErrno(int errno_r)
Make a string from errno_r.
Definition Exception.cc:233
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Definition Exception.cc:140
std::ostream & dumpError(std::ostream &str) const
Called by std::ostream & operator<<.
Definition Exception.cc:213
std::string asUserString() const
Translated error message as string suitable for the user.
Definition Exception.cc:131
CodeLocation _where
Definition Exception.h:317
History _history
Definition Exception.h:319
void addHistory(const std::string &msg_r)
Add some message text to the history.
Definition Exception.cc:189
std::string historyAsString() const
The history as string.
Definition Exception.cc:195
virtual std::ostream & dumpOn(std::ostream &str) const
Overload this to print a proper error message.
Definition Exception.cc:210
std::string asString() const
Error message provided by dumpOn as string.
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:242
const char * what() const override
Return message string.
Definition Exception.h:322
~Exception() override
Dtor.
Definition Exception.cc:121
Exception()
Default ctor.
Definition Exception.cc:94
exception_detail::CodeLocation CodeLocation
Definition Exception.h:157
std::list< std::string > History
Definition Exception.h:158
void relocate(const CodeLocation &where_r) const
Exchange location on rethrow.
Definition Exception.h:194
bool historyEmpty() const
Whether the history list is empty.
Definition Exception.h:273
void remember(const Exception &old_r)
Store an other Exception as history.
Definition Exception.cc:154
Definition Arch.h:364
String related utilities and Regular expression matching.
void do_ZYPP_RETHROW(const std::exception_ptr &excpt_r, const CodeLocation &where_r)
Definition Exception.cc:41
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
void do_ZYPP_CAUGHT(const std::exception_ptr &excpt_r, CodeLocation &&where_r)
Helper for std::exception_ptr.
Definition Exception.cc:77
std::ostream & operator<<(std::ostream &str, const CodeLocation &obj)
Definition Exception.cc:38
std::string strerror(int errno_r)
Return string describing the error_r code.
Definition String.cc:56
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition String.cc:39
Easy-to use interface to the ZYPP dependency resolver.
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
Keep FILE, FUNCTION and LINE.
Definition Exception.h:36
std::string asString() const
Location as string.
Definition Exception.cc:30
#define _(MSG)
Definition Gettext.h:39
#define INT
Definition Logger.h:104