2 * Copyright (c) 2011-2020 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 DPL_EXCEPTION_H
23 #define DPL_EXCEPTION_H
33 void LogUnhandledException(const std::string &str);
34 void LogUnhandledException(const std::string &str,
37 const char *function);
44 static unsigned int m_exceptionCount;
45 static Exception* m_lastException;
46 static void (*m_terminateHandler)();
48 static void AddRef(Exception* exception)
50 if (!m_exceptionCount) {
51 m_terminateHandler = std::set_terminate(&TerminateHandler);
55 m_lastException = exception;
58 static void UnRef(Exception* e)
60 if (m_lastException == e) {
61 m_lastException = nullptr;
66 if (!m_exceptionCount) {
67 std::set_terminate(m_terminateHandler);
68 m_terminateHandler = nullptr;
72 static void TerminateHandler()
74 if (m_lastException != nullptr) {
75 DisplayKnownException(*m_lastException);
78 DisplayUnknownException();
85 std::string m_function;
89 std::string m_message;
90 std::string m_className;
93 static std::string KnownExceptionToString(const Exception &e)
95 std::ostringstream message;
97 "\033[1;5;31m\n=== Unhandled DPL exception occurred ===\033[m\n\n";
98 message << "\033[1;33mException trace:\033[m\n\n";
99 message << e.DumpToString();
100 message << "\033[1;31m\n=== Will now abort ===\033[m\n";
102 return message.str();
105 static std::string UnknownExceptionToString()
107 std::ostringstream message;
109 "\033[1;5;31m\n=== Unhandled non-DPL exception occurred ===\033[m\n\n";
110 message << "\033[1;31m\n=== Will now abort ===\033[m\n";
112 return message.str();
115 static void DisplayKnownException(const Exception& e)
117 LogUnhandledException(KnownExceptionToString(e));
120 static void DisplayUnknownException()
122 LogUnhandledException(UnknownExceptionToString());
125 Exception(const Exception &other)
128 if (other.m_reason != nullptr) {
129 m_reason = new Exception(*other.m_reason);
134 m_message = other.m_message;
135 m_path = other.m_path;
136 m_function = other.m_function;
137 m_line = other.m_line;
139 m_className = other.m_className;
144 const Exception &operator =(const Exception &other)
146 if (this == &other) {
151 if (other.m_reason != nullptr) {
152 m_reason = new Exception(*other.m_reason);
157 m_message = other.m_message;
158 m_path = other.m_path;
159 m_function = other.m_function;
160 m_line = other.m_line;
162 m_className = other.m_className;
169 Exception(const char *path,
170 const char *function,
172 const std::string &message) :
175 m_function(function),
182 Exception(const char *path,
183 const char *function,
185 const Exception &reason,
186 const std::string &message) :
187 m_reason(new Exception(reason)),
189 m_function(function),
196 virtual ~Exception() throw()
198 if (m_reason != nullptr) {
209 if (m_reason != nullptr) {
213 // Afterward, dump exception
214 const char *file = strchr(m_path.c_str(), '/');
216 if (file == nullptr) {
217 file = m_path.c_str();
222 printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
226 m_message.empty() ? "<EMPTY>" : m_message.c_str());
229 std::string DumpToString() const
232 if (m_reason != nullptr) {
233 ret = m_reason->DumpToString();
236 const char *file = strchr(m_path.c_str(), '/');
238 if (file == nullptr) {
239 file = m_path.c_str();
247 "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
252 m_message.empty() ? "<EMPTY>" : m_message.c_str());
254 buf[sizeof(buf) - 1] = '\n';
260 Exception *GetReason() const
265 std::string GetPath() const
270 std::string GetFunction() const
280 std::string GetMessage() const
285 std::string GetClassName() const
294 #define Throw(ClassName) \
295 throw ClassName(__FILE__, __FUNCTION__, __LINE__)
297 #define ThrowMsg(ClassName, Message) \
300 std::ostringstream dplLoggingStream; \
301 dplLoggingStream << Message; \
302 throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str()); \
305 #define ReThrow(ClassName) \
306 throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception)
308 #define ReThrowMsg(ClassName, Message) \
309 throw ClassName(__FILE__, \
312 _rethrown_exception, \
315 #define Catch(ClassName) \
316 catch (const ClassName &_rethrown_exception)
318 #define DECLARE_EXCEPTION_TYPE(BaseClass, Class) \
323 Class(const char *path, \
324 const char *function, \
326 const std::string & message = std::string()) : \
327 BaseClass(path, function, line, message) \
329 BaseClass::m_className = #Class; \
332 Class(const char *path, \
333 const char *function, \
335 const DPL::Exception & reason, \
336 const std::string & message = std::string()) : \
337 BaseClass(path, function, line, reason, message) \
339 BaseClass::m_className = #Class; \
343 #define UNHANDLED_EXCEPTION_HANDLER_BEGIN try
345 #define UNHANDLED_EXCEPTION_HANDLER_END \
346 catch (const DPL::Exception &exception) \
348 std::ostringstream msg; \
349 msg << DPL::Exception::KnownExceptionToString(exception); \
350 DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \
353 catch (std::exception& e) \
355 std::ostringstream msg; \
358 msg << DPL::Exception::UnknownExceptionToString(); \
359 DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \
364 std::ostringstream msg; \
365 msg << DPL::Exception::UnknownExceptionToString(); \
366 DPL::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \
371 namespace CommonException {
373 * Internal exception definitions
375 * These should normally not happen.
376 * Usually, exception trace with internal error includes
377 * important messages.
379 DECLARE_EXCEPTION_TYPE(Exception, InternalError) ///< Unexpected error from
380 // underlying libraries or
385 #endif // DPL_EXCEPTION_H