changeset 1649:8040d56cb0b3

New function "OrthancPluginRegisterErrorCode()" to declare custom error codes
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 25 Sep 2015 16:24:13 +0200
parents a0a4fa28624c
children 9f34ebfaf2c9
files Core/HttpServer/MongooseServer.cpp NEWS OrthancServer/main.cpp Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/PluginsErrorDictionary.cpp Plugins/Engine/PluginsErrorDictionary.h Plugins/Include/orthanc/OrthancCPlugin.h Resources/CMake/Compiler.cmake
diffstat 8 files changed, 107 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/Core/HttpServer/MongooseServer.cpp	Fri Sep 25 11:33:55 2015 +0200
+++ b/Core/HttpServer/MongooseServer.cpp	Fri Sep 25 16:24:13 2015 +0200
@@ -749,12 +749,11 @@
     catch (OrthancException& e)
     {
       // Using this candidate handler results in an exception
-      LOG(ERROR) << "Exception in the HTTP handler: " << e.What();
-
       try
       {
         if (that->GetExceptionFormatter() == NULL)
         {
+          LOG(ERROR) << "Exception in the HTTP handler: " << e.What();
           output.SendStatus(e.GetHttpStatus());
         }
         else
--- a/NEWS	Fri Sep 25 11:33:55 2015 +0200
+++ b/NEWS	Fri Sep 25 16:24:13 2015 +0200
@@ -4,6 +4,11 @@
 * Add ".dcm" suffix to files in ZIP archives (cf. URI ".../archive")
 * "/tools/create-dicom": Support of binary tags encoded using data URI scheme
 
+Plugins
+-------
+
+* New function "OrthancPluginRegisterErrorCode()" to declare custom error codes
+
 Maintenance
 -----------
 
--- a/OrthancServer/main.cpp	Fri Sep 25 11:33:55 2015 +0200
+++ b/OrthancServer/main.cpp	Fri Sep 25 16:24:13 2015 +0200
@@ -327,42 +327,47 @@
                       HttpMethod method,
                       const char* uri)
   {
-    if (!describeErrors_)
-    {
-      output.SendStatus(exception.GetHttpStatus());
-      return;
-    }
-
     Json::Value message = Json::objectValue;
-    message["Method"] = EnumerationToString(method);
-    message["Uri"] = uri;
-
     ErrorCode errorCode = exception.GetErrorCode();
     HttpStatus httpStatus = exception.GetHttpStatus();
 
-    bool isPlugin = false;
+    {
+      bool isPlugin = false;
 
 #if ORTHANC_PLUGINS_ENABLED == 1
-    if (plugins_ != NULL &&
-        plugins_->GetErrorDictionary().Format(message, httpStatus, exception))
-    {
-      errorCode = ErrorCode_Plugin;
-      isPlugin = true;
-    }
+      if (plugins_ != NULL &&
+          plugins_->GetErrorDictionary().Format(message, httpStatus, exception))
+      {
+        LOG(ERROR) << "Error code " << message["PluginCode"].asInt() << " inside plugin \"" 
+                   << message["PluginName"].asString() << "\": " << message["Message"].asString();
+        errorCode = ErrorCode_Plugin;
+        isPlugin = true;
+      }
 #endif
 
-    if (!isPlugin)
-    {
-      message["Message"] = exception.What();
+      if (!isPlugin)
+      {
+        LOG(ERROR) << "Exception in the HTTP handler: " << exception.What();
+        message["Message"] = exception.What();
+      }
     }
 
-    message["HttpError"] = EnumerationToString(httpStatus);
-    message["HttpStatus"] = httpStatus;
-    message["OrthancError"] = EnumerationToString(errorCode);
-    message["OrthancStatus"] = errorCode;
+    if (!describeErrors_)
+    {
+      output.SendStatus(httpStatus);
+    }
+    else
+    {
+      message["Method"] = EnumerationToString(method);
+      message["Uri"] = uri;
+      message["HttpError"] = EnumerationToString(httpStatus);
+      message["HttpStatus"] = httpStatus;
+      message["OrthancError"] = EnumerationToString(errorCode);
+      message["OrthancStatus"] = errorCode;
 
-    std::string info = message.toStyledString();
-    output.SendStatus(httpStatus, info);
+      std::string info = message.toStyledString();
+      output.SendStatus(httpStatus, info);
+    }
   }
 };
 
--- a/Plugins/Engine/OrthancPlugins.cpp	Fri Sep 25 11:33:55 2015 +0200
+++ b/Plugins/Engine/OrthancPlugins.cpp	Fri Sep 25 16:24:13 2015 +0200
@@ -1674,6 +1674,14 @@
         return true;
       }
 
+      case _OrthancPluginService_RegisterErrorCode:
+      {
+        const _OrthancPluginRegisterErrorCode& p =
+          *reinterpret_cast<const _OrthancPluginRegisterErrorCode*>(parameters);
+        *(p.target) = pimpl_->dictionary_.Register(plugin, p.code, p.httpStatus, p.message);
+        return true;
+      }
+
       default:
       {
         // This service is unknown to the Orthanc plugin engine
--- a/Plugins/Engine/PluginsErrorDictionary.cpp	Fri Sep 25 11:33:55 2015 +0200
+++ b/Plugins/Engine/PluginsErrorDictionary.cpp	Fri Sep 25 16:24:13 2015 +0200
@@ -62,16 +62,16 @@
   }
 
 
-  OrthancPluginErrorCode PluginsErrorDictionary::Register(const std::string& pluginName,
+  OrthancPluginErrorCode PluginsErrorDictionary::Register(SharedLibrary& library,
                                                           int32_t  pluginCode,
                                                           uint16_t httpStatus,
-                                                          const char* description)
+                                                          const char* message)
   {
     std::auto_ptr<Error> error(new Error);
 
-    error->pluginName_ = pluginName;
+    error->pluginName_ = PluginsManager::GetPluginName(library);
     error->pluginCode_ = pluginCode;
-    error->description_ = description;
+    error->message_ = message;
     error->httpStatus_ = static_cast<HttpStatus>(httpStatus);
 
     OrthancPluginErrorCode code;
@@ -87,7 +87,7 @@
   }
 
 
-  bool  PluginsErrorDictionary::Format(Json::Value& message,  /* out */
+  bool  PluginsErrorDictionary::Format(Json::Value& message,    /* out */
                                        HttpStatus& httpStatus,  /* out */
                                        const OrthancException& exception)
   {
@@ -101,7 +101,7 @@
         httpStatus = error->second->httpStatus_;
         message["PluginName"] = error->second->pluginName_;
         message["PluginCode"] = error->second->pluginCode_;
-        message["Message"] = error->second->description_;
+        message["Message"] = error->second->message_;
 
         return true;
       }
--- a/Plugins/Engine/PluginsErrorDictionary.h	Fri Sep 25 11:33:55 2015 +0200
+++ b/Plugins/Engine/PluginsErrorDictionary.h	Fri Sep 25 16:24:13 2015 +0200
@@ -36,6 +36,7 @@
 
 #include "../Include/orthanc/OrthancCPlugin.h"
 #include "../../Core/OrthancException.h"
+#include "SharedLibrary.h"
 
 #include <map>
 #include <string>
@@ -54,7 +55,7 @@
       std::string  pluginName_;
       int32_t      pluginCode_;
       HttpStatus   httpStatus_;
-      std::string  description_;
+      std::string  message_;
     };
     
     typedef std::map<int32_t, Error*>  Errors;
@@ -68,12 +69,12 @@
 
     ~PluginsErrorDictionary();
 
-    OrthancPluginErrorCode  Register(const std::string& pluginName,
+    OrthancPluginErrorCode  Register(SharedLibrary& library,
                                      int32_t  pluginCode,
                                      uint16_t httpStatus,
-                                     const char* description);
+                                     const char* message);
 
-    bool  Format(Json::Value& message,  /* out */
+    bool  Format(Json::Value& message,    /* out */
                  HttpStatus& httpStatus,  /* out */
                  const OrthancException& exception);
   };
--- a/Plugins/Include/orthanc/OrthancCPlugin.h	Fri Sep 25 11:33:55 2015 +0200
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h	Fri Sep 25 16:24:13 2015 +0200
@@ -383,6 +383,7 @@
     _OrthancPluginService_WriteFile = 16,
     _OrthancPluginService_GetErrorDescription = 17,
     _OrthancPluginService_CallHttpClient = 18,
+    _OrthancPluginService_RegisterErrorCode = 19,
 
     /* Registration of callbacks */
     _OrthancPluginService_RegisterRestCallback = 1000,
@@ -3598,7 +3599,6 @@
     OrthancPluginContentType    type;
   } _OrthancPluginStorageAreaRemove;
 
-
   /**
    * @brief Remove a file from the storage area.
    *
@@ -3628,6 +3628,55 @@
 
 
 
+  typedef struct
+  {
+    OrthancPluginErrorCode*  target;
+    int32_t                  code;
+    uint16_t                 httpStatus;
+    const char*              message;
+  } _OrthancPluginRegisterErrorCode;
+  
+  /**
+   * @brief Declare a custom error code for this plugin.
+   *
+   * This function declares a custom error code that can be generated
+   * by this plugin. This declaration is used to enrich the body of
+   * the HTTP answer in the case of an error, and to set the proper
+   * HTTP status code.
+   *
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param code The error code that is internal to this plugin.
+   * @param httpStatus The HTTP status corresponding to this error.
+   * @param message The description of the error.
+   * @return The error code that has been assigned inside the Orthanc core.
+   * @ingroup Toolbox
+   **/
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode  OrthancPluginRegisterErrorCode(
+    OrthancPluginContext*    context,
+    int32_t                  code,
+    uint16_t                 httpStatus,
+    const char*              message)
+  {
+    OrthancPluginErrorCode target;
+
+    _OrthancPluginRegisterErrorCode params;
+    params.target = &target;
+    params.code = code;
+    params.httpStatus = httpStatus;
+    params.message = message;
+
+    if (context->InvokeService(context, _OrthancPluginService_RegisterErrorCode, &params) == OrthancPluginErrorCode_Success)
+    {
+      return target;
+    }
+    else
+    {
+      /* There was an error while assigned the error. Use a generic code. */
+      return OrthancPluginErrorCode_Plugin;
+    }
+  }
+
+
 #ifdef  __cplusplus
 }
 #endif
--- a/Resources/CMake/Compiler.cmake	Fri Sep 25 11:33:55 2015 +0200
+++ b/Resources/CMake/Compiler.cmake	Fri Sep 25 16:24:13 2015 +0200
@@ -50,7 +50,7 @@
     ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
     ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
   set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
-  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -Wl,--version-script=${CMAKE_SOURCE_DIR}/Plugins/Samples/Common/VersionScript.map")
+  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -Wl,--version-script=${ORTHANC_ROOT}/Plugins/Samples/Common/VersionScript.map")
 
   # Remove the "-rdynamic" option
   # http://www.mail-archive.com/cmake@cmake.org/msg08837.html
@@ -108,7 +108,7 @@
   endif()
 
 elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
-  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -exported_symbols_list ${CMAKE_SOURCE_DIR}/Plugins/Samples/Common/ExportedSymbols.list")
+  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -exported_symbols_list ${ORTHANC_ROOT}/Plugins/Samples/Common/ExportedSymbols.list")
 
   add_definitions(
     -D_XOPEN_SOURCE=1