2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief Header file for base exception
22 #ifndef CENT_KEY_EXCEPTION_H
23 #define CENT_KEY_EXCEPTION_H
31 #include <symbol-visibility.h>
34 COMMON_API void LogUnhandledException(const std::string &str);
35 COMMON_API void LogUnhandledException(const std::string &str,
38 const char *function);
42 class COMMON_API Exception
45 static unsigned int m_exceptionCount;
46 static Exception* m_lastException;
47 static void (*m_terminateHandler)();
49 static void AddRef(Exception* exception)
51 if (!m_exceptionCount) {
52 m_terminateHandler = std::set_terminate(&TerminateHandler);
56 m_lastException = exception;
59 static void UnRef(Exception* e)
61 if (m_lastException == e) {
62 m_lastException = NULL;
67 if (!m_exceptionCount) {
68 std::set_terminate(m_terminateHandler);
69 m_terminateHandler = NULL;
73 static void TerminateHandler()
75 if (m_lastException != NULL) {
76 DisplayKnownException(*m_lastException);
79 DisplayUnknownException();
86 std::string m_function;
90 std::string m_message;
91 std::string m_className;
94 static std::string KnownExceptionToString(const Exception &e)
96 std::ostringstream message;
98 "\033[1;5;31m\n=== Unhandled CKM exception occurred ===\033[m\n\n";
99 message << "\033[1;33mException trace:\033[m\n\n";
100 message << e.DumpToString();
101 message << "\033[1;31m\n=== Will now abort ===\033[m\n";
103 return message.str();
106 static std::string UnknownExceptionToString()
108 std::ostringstream message;
110 "\033[1;5;31m\n=== Unhandled non-CKM exception occurred ===\033[m\n\n";
111 message << "\033[1;31m\n=== Will now abort ===\033[m\n";
113 return message.str();
116 static void DisplayKnownException(const Exception& e)
118 LogUnhandledException(KnownExceptionToString(e).c_str());
121 static void DisplayUnknownException()
123 LogUnhandledException(UnknownExceptionToString().c_str());
126 Exception(const Exception &other)
129 if (other.m_reason != NULL) {
130 m_reason = new Exception(*other.m_reason);
135 m_message = other.m_message;
136 m_path = other.m_path;
137 m_function = other.m_function;
138 m_line = other.m_line;
140 m_className = other.m_className;
145 const Exception &operator =(const Exception &other)
147 if (this == &other) {
152 if (other.m_reason != NULL) {
153 m_reason = new Exception(*other.m_reason);
158 m_message = other.m_message;
159 m_path = other.m_path;
160 m_function = other.m_function;
161 m_line = other.m_line;
163 m_className = other.m_className;
170 Exception(const char *path,
171 const char *function,
173 const std::string &message) :
176 m_function(function),
183 Exception(const char *path,
184 const char *function,
186 const Exception &reason,
187 const std::string &message) :
188 m_reason(new Exception(reason)),
190 m_function(function),
197 virtual ~Exception() throw()
199 if (m_reason != NULL) {
210 if (m_reason != NULL) {
214 // Afterward, dump exception
215 const char *file = strchr(m_path.c_str(), '/');
218 file = m_path.c_str();
223 printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
227 m_message.empty() ? "<EMPTY>" : m_message.c_str());
230 std::string DumpToString() const
233 if (m_reason != NULL) {
234 ret = m_reason->DumpToString();
237 const char *file = strchr(m_path.c_str(), '/');
240 file = m_path.c_str();
248 "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
253 m_message.empty() ? "<EMPTY>" : m_message.c_str());
255 buf[sizeof(buf) - 1] = '\n';
261 Exception *GetReason() const
266 std::string GetPath() const
271 std::string GetFunction() const
281 std::string GetMessage() const
286 std::string GetClassName() const
295 #define Throw(ClassName) \
296 throw ClassName(__FILE__, __FUNCTION__, __LINE__)
298 #define ThrowMsg(ClassName, Message) \
301 std::ostringstream dplLoggingStream; \
302 dplLoggingStream << Message; \
303 throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str()); \
306 #define ReThrow(ClassName) \
307 throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception)
309 #define ReThrowMsg(ClassName, Message) \
310 throw ClassName(__FILE__, \
313 _rethrown_exception, \
316 #define Catch(ClassName) \
317 catch (const ClassName &_rethrown_exception)
319 #define DECLARE_EXCEPTION_TYPE(BaseClass, Class) \
324 Class(const char *path, \
325 const char *function, \
327 const std::string & message = std::string()) : \
328 BaseClass(path, function, line, message) \
330 BaseClass::m_className = #Class; \
333 Class(const char *path, \
334 const char *function, \
336 const CKM::Exception & reason, \
337 const std::string & message = std::string()) : \
338 BaseClass(path, function, line, reason, message) \
340 BaseClass::m_className = #Class; \
344 #define UNHANDLED_EXCEPTION_HANDLER_BEGIN try
346 #define UNHANDLED_EXCEPTION_HANDLER_END \
347 catch (const CKM::Exception &exception) \
349 std::ostringstream msg; \
350 msg << CKM::Exception::KnownExceptionToString(exception); \
351 CKM::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \
354 catch (std::exception& e) \
356 std::ostringstream msg; \
359 msg << CKM::Exception::UnknownExceptionToString(); \
360 CKM::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \
365 std::ostringstream msg; \
366 msg << CKM::Exception::UnknownExceptionToString(); \
367 CKM::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \
372 namespace CommonException {
374 * Internal exception definitions
376 * These should normally not happen.
377 * Usually, exception trace with internal error includes
378 * important messages.
380 DECLARE_EXCEPTION_TYPE(Exception, InternalError) ///< Unexpected error from
381 // underlying libraries or
386 #endif // CENT_KEY_EXCEPTION_H