1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/Exception.h
12 #ifndef ZYPP_BASE_EXCEPTION_H
13 #define ZYPP_BASE_EXCEPTION_H
19 ///////////////////////////////////////////////////////////////////
21 { /////////////////////////////////////////////////////////////////
22 ///////////////////////////////////////////////////////////////////
23 namespace exception_detail
24 { /////////////////////////////////////////////////////////////////
26 /** Keep _FILE_, _FUNCTION_ and _LINE_.
27 * Construct it using the \ref ZYPP_EX_CODELOCATION macro.
31 friend std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
39 CodeLocation( const std::string & file_r,
40 const std::string & func_r,
42 : _file( file_r ), _func( func_r ), _line( line_r )
45 /** Location as string */
46 std::string asString() const;
53 ///////////////////////////////////////////////////////////////////
55 /** Create CodeLocation object storing the current location. */
56 //#define ZYPP_EX_CODELOCATION ::zypp::exception_detail::CodeLocation(__FILE__,__FUNCTION__,__LINE__)
57 #define ZYPP_EX_CODELOCATION ::zypp::exception_detail::CodeLocation(( *__FILE__ == '/' ? strrchr( __FILE__, '/' ) + 1 : __FILE__ ),__FUNCTION__,__LINE__)
59 /** \relates CodeLocation Stream output */
60 std::ostream & operator<<( std::ostream & str, const CodeLocation & obj );
62 /////////////////////////////////////////////////////////////////
63 } // namespace exception_detail
64 ///////////////////////////////////////////////////////////////////
66 ///////////////////////////////////////////////////////////////////
68 // CLASS NAME : Exception
69 /** Base class for Exception.
71 * Exception offers to store a message string passed to the ctor.
72 * Derived classes may provide additional information. Overload
73 * \ref dumpOn to provide a proper error text.
75 * \li Use \ref ZYPP_THROW to throw exceptions.
76 * \li Use \ref ZYPP_CAUGHT If you caught an exceptions in order to handle it.
77 * \li Use \ref ZYPP_RETHROW to rethrow a caught exception.
79 * The use of these macros is not mandatory. but \c ZYPP_THROW and
80 * \c ZYPP_RETHROW will adjust the code location information stored in
81 * the Exception. All three macros will drop a line in the logfile.
88 * 47 ZYPP_THROW( Exception("Something bad happened.") );
90 * 49 catch ( Exception & excpt )
92 * 51 ZYPP_RETHROW( excpt );
96 * 55 catch ( Exception & excpt )
98 * 57 ZYPP_CAUGHT( excpt );
101 * The above produces the following log lines:
103 * Main.cc(main):47 THROW: Main.cc(main):47: Something bad happened.
104 * Main.cc(main):51 RETHROW: Main.cc(main):47: Something bad happened.
105 * Main.cc(main):57 CAUGHT: Main.cc(main):51: Something bad happened.
108 * \todo That's a draft to have a common way of throwing exceptions.
109 * Most probabely we'll finally use blocxx exceptions. Here, but not
110 * in the remaining code of zypp. If we can we should try to wrap
111 * the blocxx macros and typedef the classes in here.
113 * \todo maybe location and message stack.
115 class Exception : public std::exception
117 friend std::ostream & operator<<( std::ostream & str, const Exception & obj );
120 typedef exception_detail::CodeLocation CodeLocation;
123 * Use \ref ZYPP_THROW to throw exceptions.
127 /** Ctor taking a message.
128 * Use \ref ZYPP_THROW to throw exceptions.
130 Exception( const std::string & msg_r );
133 virtual ~Exception() throw();
135 /** Return CodeLocation. */
136 const CodeLocation & where() const
139 /** Exchange location on rethrow. */
140 void relocate( const CodeLocation & where_r ) const
141 { _where = where_r; }
143 /** Return the message string provided to the ctor.
144 * \note This is not neccessarily the complete error message.
145 * The whole error message is provided by \ref asString or
148 const std::string & msg() const
151 /** Error message provided by \ref dumpOn as string. */
152 std::string asString() const;
154 /** Translated error message as string suitable for the user. */
155 std::string asUserString() const;
159 /** Overload this to print a proper error message. */
160 virtual std::ostream & dumpOn( std::ostream & str ) const;
163 /** Make a string from \a errno_r. */
164 static std::string strErrno( int errno_r );
165 /** Make a string from \a errno_r and \a msg_r. */
166 static std::string strErrno( int errno_r, const std::string & msg_r );
169 /** Drop a logline on throw, catch or rethrow.
170 * Used by \ref ZYPP_THROW macros.
172 static void log( const Exception & excpt_r, const CodeLocation & where_r,
173 const char *const prefix_r );
176 mutable CodeLocation _where;
179 /** Return message string. */
180 virtual const char * what() const throw()
181 { return _msg.c_str(); }
183 /** Called by <tt>std::ostream & operator\<\<</tt>.
184 * Prints \ref CodeLocation and the error message provided by
187 std::ostream & dumpError( std::ostream & str ) const;
189 ///////////////////////////////////////////////////////////////////
191 /** \relates Exception Stream output */
192 std::ostream & operator<<( std::ostream & str, const Exception & obj );
194 ///////////////////////////////////////////////////////////////////
196 /** Helper for \ref ZYPP_THROW. */
197 template<class _Excpt>
198 void _ZYPP_THROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
200 excpt_r.relocate( where_r );
201 Exception::log( excpt_r, where_r, "THROW: " );
205 /** Helper for \ref ZYPP_THROW. */
206 template<class _Excpt>
207 void _ZYPP_CAUGHT( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
209 Exception::log( excpt_r, where_r, "CAUGHT: " );
212 /** Helper for \ref ZYPP_THROW. */
213 template<class _Excpt>
214 void _ZYPP_RETHROW( const _Excpt & excpt_r, const exception_detail::CodeLocation & where_r )
216 Exception::log( excpt_r, where_r, "RETHROW: " );
217 excpt_r.relocate( where_r );
221 ///////////////////////////////////////////////////////////////////
223 /** \defgroup ZYPP_THROW ZYPP_THROW macros
224 * Macros for throwing Exception.
225 * \see \ref zypp::Exception for an example.
228 /** Drops a logline and throws the Exception. */
229 #define ZYPP_THROW(EXCPT)\
230 _ZYPP_THROW( EXCPT, ZYPP_EX_CODELOCATION )
232 /** Drops a logline telling the Exception was caught (in order to handle it). */
233 #define ZYPP_CAUGHT(EXCPT)\
234 _ZYPP_CAUGHT( EXCPT, ZYPP_EX_CODELOCATION )
236 /** Drops a logline and rethrows, updating the CodeLocation. */
237 #define ZYPP_RETHROW(EXCPT)\
238 _ZYPP_RETHROW( EXCPT, ZYPP_EX_CODELOCATION )
241 /** Throw Exception built from a message string. */
242 #define ZYPP_THROW_MSG(EXCPTTYPE, MSG)\
243 ZYPP_THROW( EXCPTTYPE( MSG ) )
245 /** Throw Exception built from errno. */
246 #define ZYPP_THROW_ERRNO(EXCPTTYPE)\
247 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno) ) )
249 /** Throw Exception built from errno provided as argument. */
250 #define ZYPP_THROW_ERRNO1(EXCPTTYPE, ERRNO)\
251 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO) ) )
253 /** Throw Exception built from errno and a message string. */
254 #define ZYPP_THROW_ERRNO_MSG(EXCPTTYPE, MSG)\
255 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(errno,MSG) ) )
257 /** Throw Exception built from errno provided as argument and a message string */
258 #define ZYPP_THROW_ERRNO_MSG1(EXCPTTYPE, ERRNO,MSG)\
259 ZYPP_THROW( EXCPTTYPE( ::zypp::Exception::strErrno(ERRNO,MSG) ) )
262 /////////////////////////////////////////////////////////////////
264 ///////////////////////////////////////////////////////////////////
265 #endif // ZYPP_BASE_EXCEPTION_H