瀏覽代碼

Fix PluginException and ServiceException to report cause.

The cause of an exception is now stored as a QString, because copying
std::exception objects discards the subclass information.
Sascha Zelzer 14 年之前
父節點
當前提交
59ea7b31d2

+ 17 - 14
Libs/PluginFramework/ctkPluginException.cpp

@@ -22,18 +22,24 @@
 #include "ctkPluginException.h"
 
 
-ctkPluginException::ctkPluginException(const QString& msg, const Type& type, const std::exception& cause)
+ctkPluginException::ctkPluginException(const QString& msg, const Type& type, const std::exception* cause)
   : std::runtime_error(msg.toStdString()),
-    type(type), cause(cause)
+    type(type)
 {
-
+  if (cause)
+  {
+    this->cause = QString(cause->what());
+  }
 }
 
-ctkPluginException::ctkPluginException(const QString& msg, const std::exception& cause)
+ctkPluginException::ctkPluginException(const QString& msg, const std::exception* cause)
   : std::runtime_error(msg.toStdString()),
-    type(UNSPECIFIED), cause(cause)
+    type(UNSPECIFIED)
 {
-
+  if (cause)
+  {
+    this->cause = QString(cause->what());
+  }
 }
 
 ctkPluginException::ctkPluginException(const ctkPluginException& o)
@@ -50,14 +56,14 @@ ctkPluginException& ctkPluginException::operator=(const ctkPluginException& o)
   return *this;
 }
 
-std::exception ctkPluginException::getCause() const
+QString ctkPluginException::getCause() const
 {
   return cause;
 }
 
-void ctkPluginException::setCause(const std::exception& cause) throw(std::logic_error)
+void ctkPluginException::setCause(const QString& cause) throw(std::logic_error)
 {
-  if (!cause.what()) throw std::logic_error("The cause for this ctkPluginException instance is already set");
+  if (!this->cause.isEmpty()) throw std::logic_error("The cause for this ctkPluginException instance is already set");
 
   this->cause = cause;
 }
@@ -71,8 +77,8 @@ const char* ctkPluginException::what() const throw()
 {
   static std::string fullMsg;
   fullMsg = std::string(std::runtime_error::what());
-  const char* causeMsg = getCause().what();
-  if (causeMsg) fullMsg += std::string("\n  Caused by: ") + causeMsg;
+  QString causeMsg = getCause();
+  if (!causeMsg.isEmpty()) fullMsg += std::string("\n  Caused by: ") + causeMsg.toStdString();
 
   return fullMsg.c_str();
 }
@@ -82,8 +88,5 @@ QDebug operator<<(QDebug dbg, const ctkPluginException& exc)
 {
   dbg << "ctkPluginException:" << exc.what();
 
-  const char* causeMsg = exc.getCause().what();
-  if (causeMsg) dbg << "  Caused by:" << causeMsg;
-
   return dbg.maybeSpace();
 }

+ 5 - 5
Libs/PluginFramework/ctkPluginException.h

@@ -74,16 +74,16 @@ public:
     DUPLICATE_BUNDLE_ERROR
   };
 
-  ctkPluginException(const QString& msg, const Type& type = UNSPECIFIED, const std::exception& cause = std::exception());
-  ctkPluginException(const QString& msg, const std::exception& cause);
+  ctkPluginException(const QString& msg, const Type& type = UNSPECIFIED, const std::exception* cause = 0);
+  ctkPluginException(const QString& msg, const std::exception* cause);
 
   ctkPluginException(const ctkPluginException& o);
   ctkPluginException& operator=(const ctkPluginException& o);
 
   ~ctkPluginException() throw() {}
 
-  std::exception getCause() const;
-  void setCause(const std::exception&) throw(std::logic_error);
+  QString getCause() const;
+  void setCause(const QString&) throw(std::logic_error);
   Type getType() const;
 
   const char* what() const throw();
@@ -92,7 +92,7 @@ public:
 private:
 
   Type type;
-  std::exception cause;
+  QString cause;
 
 };
 

+ 2 - 2
Libs/PluginFramework/ctkPluginPrivate.cpp

@@ -248,7 +248,7 @@ void ctkPluginPrivate::stop0(bool wasStarted)
       catch (const std::exception& e)
       {
         savedException = new ctkPluginException("ctkPlugin::stop: PluginActivator stop failed",
-                                                ctkPluginException::ACTIVATOR_ERROR, e);
+                                                ctkPluginException::ACTIVATOR_ERROR, &e);
       }
       if (state == ctkPlugin::UNINSTALLED)
       {
@@ -344,7 +344,7 @@ void ctkPluginPrivate::start0()
   }
   catch (const std::exception& e)
   {
-    throw ctkPluginException("ctkPlugin start failed", ctkPluginException::ACTIVATOR_ERROR, e);
+    throw ctkPluginException("ctkPlugin start failed", ctkPluginException::ACTIVATOR_ERROR, &e);
   }
 
   qDebug() << "activating #" << id << "completed.";

+ 1 - 1
Libs/PluginFramework/ctkPlugins.cpp

@@ -126,7 +126,7 @@
   //      else
   //      {
         throw ctkPluginException(QString("Failed to install plugin: ") + QString(e.what()),
-                                ctkPluginException::UNSPECIFIED, e);
+                                ctkPluginException::UNSPECIFIED, &e);
   //      }
       }
     }

+ 25 - 12
Libs/PluginFramework/ctkServiceException.cpp

@@ -24,18 +24,24 @@
 #include <QDebug>
 
 
-ctkServiceException::ctkServiceException(const QString& msg, const Type& type, const std::exception& cause)
+ctkServiceException::ctkServiceException(const QString& msg, const Type& type, const std::exception* cause)
   : std::runtime_error(msg.toStdString()),
-    type(type), cause(cause)
+    type(type)
 {
-
+  if (cause)
+  {
+    this->cause = QString(cause->what());
+  }
 }
 
-ctkServiceException::ctkServiceException(const QString& msg, const std::exception& cause)
+ctkServiceException::ctkServiceException(const QString& msg, const std::exception* cause)
   : std::runtime_error(msg.toStdString()),
-    type(UNSPECIFIED), cause(cause)
+    type(UNSPECIFIED)
 {
-
+  if (cause)
+  {
+    this->cause = QString(cause->what());
+  }
 }
 
 ctkServiceException::ctkServiceException(const ctkServiceException& o)
@@ -52,14 +58,14 @@ ctkServiceException& ctkServiceException::operator=(const ctkServiceException& o
   return *this;
 }
 
-std::exception ctkServiceException::getCause() const
+QString ctkServiceException::getCause() const
 {
   return cause;
 }
 
-void ctkServiceException::setCause(const std::exception& cause) throw(std::logic_error)
+void ctkServiceException::setCause(const QString& cause) throw(std::logic_error)
 {
-  if (!cause.what()) throw std::logic_error("The cause for this ctkServiceException instance is already set");
+  if (!this->cause.isEmpty()) throw std::logic_error("The cause for this ctkServiceException instance is already set");
 
   this->cause = cause;
 }
@@ -69,12 +75,19 @@ ctkServiceException::Type ctkServiceException::getType() const
   return type;
 }
 
+const char* ctkServiceException::what() const throw()
+{
+  static std::string fullMsg;
+  fullMsg = std::string(std::runtime_error::what());
+  QString causeMsg = getCause();
+  if (!causeMsg.isEmpty()) fullMsg += std::string("\n  Caused by: ") + causeMsg.toStdString();
+
+  return fullMsg.c_str();
+}
+
 QDebug operator<<(QDebug dbg, const ctkServiceException& exc)
 {
   dbg << "ctkServiceException:" << exc.what();
 
-  const char* causeMsg = exc.getCause().what();
-  if (causeMsg) dbg << "  Caused by:" << causeMsg;
-
   return dbg.maybeSpace();
 }

+ 6 - 5
Libs/PluginFramework/ctkServiceException.h

@@ -62,23 +62,24 @@ public:
     REMOTE 				= 5
   };
 
-  ctkServiceException(const QString& msg, const Type& type = UNSPECIFIED, const std::exception& cause = std::exception());
-  ctkServiceException(const QString& msg, const std::exception& cause);
+  ctkServiceException(const QString& msg, const Type& type = UNSPECIFIED, const std::exception* cause = 0);
+  ctkServiceException(const QString& msg, const std::exception* cause);
 
   ctkServiceException(const ctkServiceException& o);
   ctkServiceException& operator=(const ctkServiceException& o);
 
   ~ctkServiceException() throw() {}
 
-  std::exception getCause() const;
-  void setCause(const std::exception&) throw(std::logic_error);
+  QString getCause() const;
+  void setCause(const QString&) throw(std::logic_error);
   Type getType() const;
 
+  const char* what() const throw();
 
 private:
 
   Type type;
-  std::exception cause;
+  QString cause;
 
 };
 

+ 1 - 1
Libs/PluginFramework/ctkServiceReferencePrivate.cpp

@@ -59,7 +59,7 @@ QObject* ctkServiceReferencePrivate::getService(ctkPlugin* plugin)
           catch (const std::exception& pe)
           {
             ctkServiceException se("ctkServiceFactory throw an exception",
-                                   ctkServiceException::FACTORY_EXCEPTION, pe);
+                                   ctkServiceException::FACTORY_EXCEPTION, &pe);
             plugin->d_func()->fwCtx->listeners.frameworkError
                 (registration->plugin->q_func(), se);
             return 0;