changeset 1575:f8aae45011c9

exceptions now carry HTTP status
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 25 Aug 2015 14:00:57 +0200
parents 0c29ebe80ac9
children de54c19fc44d
files Core/Enumerations.cpp Core/Enumerations.h Core/HttpServer/MongooseServer.cpp Core/OrthancException.cpp Core/OrthancException.h
diffstat 5 files changed, 168 insertions(+), 131 deletions(-) [+]
line wrap: on
line diff
--- a/Core/Enumerations.cpp	Tue Aug 25 13:37:57 2015 +0200
+++ b/Core/Enumerations.cpp	Tue Aug 25 14:00:57 2015 +0200
@@ -40,6 +40,100 @@
 
 namespace Orthanc
 {
+  const char* EnumerationToString(ErrorCode error)
+  {
+    switch (error)
+    {
+      case ErrorCode_Success:
+        return "Success";
+
+      case ErrorCode_Custom:
+        return "Custom error, see the attached error message";
+
+      case ErrorCode_InternalError:
+        return "Internal error";
+
+      case ErrorCode_NotImplemented:
+        return "Not implemented yet";
+
+      case ErrorCode_ParameterOutOfRange:
+        return "Parameter out of range";
+
+      case ErrorCode_NotEnoughMemory:
+        return "Not enough memory";
+
+      case ErrorCode_BadParameterType:
+        return "Bad type for a parameter";
+
+      case ErrorCode_BadSequenceOfCalls:
+        return "Bad sequence of calls";
+
+      case ErrorCode_UriSyntax:
+        return "Badly formatted URI";
+
+      case ErrorCode_InexistentFile:
+        return "Inexistent file";
+
+      case ErrorCode_BadFileFormat:
+        return "Bad file format";
+
+      case ErrorCode_CannotWriteFile:
+        return "Cannot write to file";
+
+      case ErrorCode_Timeout:
+        return "Timeout";
+
+      case ErrorCode_UnknownResource:
+        return "Unknown resource";
+
+      case ErrorCode_IncompatibleDatabaseVersion:
+        return "Incompatible version of the database";
+
+      case ErrorCode_FullStorage:
+        return "The file storage is full";
+
+      case ErrorCode_InexistentItem:
+        return "Accessing an inexistent item";
+
+      case ErrorCode_BadRequest:
+        return "Bad request";
+
+      case ErrorCode_NetworkProtocol:
+        return "Error in the network protocol";
+
+      case ErrorCode_CorruptedFile:
+        return "Corrupted file (inconsistent MD5 hash)";
+
+      case ErrorCode_InexistentTag:
+        return "Inexistent tag";
+
+      case ErrorCode_ReadOnly:
+        return "Cannot modify a read-only data structure";
+
+      case ErrorCode_IncompatibleImageSize:
+        return "Incompatible size of the images";
+
+      case ErrorCode_IncompatibleImageFormat:
+        return "Incompatible format of the images";
+
+      case ErrorCode_SharedLibrary:
+        return "Error while using a shared library (plugin)";
+
+      case ErrorCode_SystemCommand:
+        return "Error while calling a system command";
+
+      case ErrorCode_Plugin:
+        return "Error encountered inside a plugin";
+
+      case ErrorCode_Database:
+        return "Error with the database engine";
+
+      default:
+        return "Unknown error code";
+    }
+  }
+
+
   const char* EnumerationToString(HttpMethod method)
   {
     switch (method)
--- a/Core/Enumerations.h	Tue Aug 25 13:37:57 2015 +0200
+++ b/Core/Enumerations.h	Tue Aug 25 14:00:57 2015 +0200
@@ -359,6 +359,8 @@
   };
 
 
+  const char* EnumerationToString(ErrorCode code);
+
   const char* EnumerationToString(HttpMethod method);
 
   const char* EnumerationToString(HttpStatus status);
--- a/Core/HttpServer/MongooseServer.cpp	Tue Aug 25 13:37:57 2015 +0200
+++ b/Core/HttpServer/MongooseServer.cpp	Tue Aug 25 14:00:57 2015 +0200
@@ -734,12 +734,12 @@
       }
       catch (boost::bad_lexical_cast&)
       {
-        throw OrthancException(ErrorCode_BadParameterType);
+        throw OrthancException(ErrorCode_BadParameterType, HttpStatus_400_BadRequest);
       }
       catch (std::runtime_error&)
       {
         // Presumably an error while parsing the JSON body
-        throw OrthancException(ErrorCode_BadRequest);
+        throw OrthancException(ErrorCode_BadRequest, HttpStatus_400_BadRequest);
       }
 
       if (!found)
@@ -752,39 +752,20 @@
       // Using this candidate handler results in an exception
       LOG(ERROR) << "Exception in the HTTP handler: " << e.What();
 
-      HttpStatus status;
+      Json::Value message = Json::objectValue;
+      message["HttpError"] = EnumerationToString(e.GetHttpStatus());
+      message["HttpStatus"] = e.GetHttpStatus();
+      message["Message"] = e.What();
+      message["Method"] = EnumerationToString(method);
+      message["OrthancError"] = EnumerationToString(e.GetErrorCode());
+      message["OrthancStatus"] = e.GetErrorCode();
+      message["Uri"] = request->uri;
+
+      std::string info = message.toStyledString();
 
       try
       {
-        switch (e.GetErrorCode())
-        {
-          case ErrorCode_InexistentFile:
-          case ErrorCode_InexistentItem:
-          case ErrorCode_UnknownResource:
-            status = HttpStatus_404_NotFound;
-            break;
-
-          case ErrorCode_BadRequest:
-          case ErrorCode_UriSyntax:
-          case ErrorCode_BadParameterType:
-            status = HttpStatus_400_BadRequest;
-            break;
-
-          default:
-	    status = HttpStatus_500_InternalServerError;
-	    break;
-        }
-
-	Json::Value message = Json::objectValue;
-	message["HttpStatus"] = status;
-	message["HttpError"] = EnumerationToString(status);
-	message["OrthancStatus"] = e.GetErrorCode();
-	message["OrthancError"] = e.GetDescription(e.GetErrorCode());
-	message["Message"] = e.What();
-	message["Uri"] = request->uri;
-	message["Method"] = EnumerationToString(method);
-	std::string s = message.toStyledString();
-	output.SendStatus(status, s);
+	output.SendStatus(e.GetHttpStatus(), info);
       }
       catch (OrthancException&)
       {
--- a/Core/OrthancException.cpp	Tue Aug 25 13:37:57 2015 +0200
+++ b/Core/OrthancException.cpp	Tue Aug 25 14:00:57 2015 +0200
@@ -35,109 +35,56 @@
 
 namespace Orthanc
 {
+  HttpStatus OrthancException::ConvertToHttpStatus(ErrorCode code)
+  {
+    switch (code)
+    {
+      case ErrorCode_Success:
+      {
+        return HttpStatus_200_Ok;
+      }
+
+      case ErrorCode_InexistentFile:
+      case ErrorCode_InexistentItem:
+      case ErrorCode_InexistentTag:
+      case ErrorCode_UnknownResource:
+      {
+        return HttpStatus_404_NotFound;
+      }
+
+      case ErrorCode_BadFileFormat:
+      case ErrorCode_BadParameterType:
+      case ErrorCode_BadRequest:
+      case ErrorCode_ParameterOutOfRange:
+      case ErrorCode_UriSyntax:
+      {
+        return HttpStatus_400_BadRequest;
+        break;
+      }
+
+      default:
+      {
+        return HttpStatus_500_InternalServerError;
+      }
+    }
+  }
+
   const char* OrthancException::What() const
   {
-    if (error_ == ErrorCode_Custom)
+    if (errorCode_ == ErrorCode_Custom)
     {
       return custom_.c_str();
     }
     else
     {
-      return GetDescription(error_);
+      return EnumerationToString(errorCode_);
     }
   }
 
 
-  const char* OrthancException::GetDescription(ErrorCode error)
+  OrthancException::OrthancException(ErrorCode errorCode) : 
+    errorCode_(errorCode),
+    httpStatus_(ConvertToHttpStatus(errorCode))
   {
-    switch (error)
-    {
-      case ErrorCode_Success:
-        return "Success";
-
-      case ErrorCode_ParameterOutOfRange:
-        return "Parameter out of range";
-
-      case ErrorCode_NotImplemented:
-        return "Not implemented yet";
-
-      case ErrorCode_InternalError:
-        return "Internal error";
-
-      case ErrorCode_NotEnoughMemory:
-        return "Not enough memory";
-
-      case ErrorCode_UriSyntax:
-        return "Badly formatted URI";
-
-      case ErrorCode_BadParameterType:
-        return "Bad type for a parameter";
-
-      case ErrorCode_InexistentFile:
-        return "Inexistent file";
-
-      case ErrorCode_BadFileFormat:
-        return "Bad file format";
-
-      case ErrorCode_CannotWriteFile:
-        return "Cannot write to file";
-
-      case ErrorCode_Timeout:
-        return "Timeout";
-
-      case ErrorCode_UnknownResource:
-        return "Unknown resource";
-
-      case ErrorCode_BadSequenceOfCalls:
-        return "Bad sequence of calls";
-
-      case ErrorCode_IncompatibleDatabaseVersion:
-        return "Incompatible version of the database";
-
-      case ErrorCode_FullStorage:
-        return "The file storage is full";
-
-      case ErrorCode_InexistentItem:
-        return "Accessing an inexistent item";
-
-      case ErrorCode_BadRequest:
-        return "Bad request";
-
-      case ErrorCode_NetworkProtocol:
-        return "Error in the network protocol";
-
-      case ErrorCode_CorruptedFile:
-        return "Corrupted file (inconsistent MD5 hash)";
-
-      case ErrorCode_InexistentTag:
-        return "Inexistent tag";
-
-      case ErrorCode_ReadOnly:
-        return "Cannot modify a read-only data structure";
-
-      case ErrorCode_IncompatibleImageSize:
-        return "Incompatible size of the images";
-
-      case ErrorCode_IncompatibleImageFormat:
-        return "Incompatible format of the images";
-
-      case ErrorCode_SharedLibrary:
-        return "Error while using a shared library (plugin)";
-
-      case ErrorCode_SystemCommand:
-        return "Error while calling a system command";
-
-      case ErrorCode_Plugin:
-        return "Error encountered inside a plugin";
-
-      case ErrorCode_Database:
-        return "Error with the database engine";
-
-      case ErrorCode_Custom:
-        return "See the attached error message";
-
-      default:
-        return "Unknown error code";
-    }
   }
 }
--- a/Core/OrthancException.h	Tue Aug 25 13:37:57 2015 +0200
+++ b/Core/OrthancException.h	Tue Aug 25 14:00:57 2015 +0200
@@ -40,31 +40,44 @@
   class OrthancException
   {
   protected:
-    ErrorCode error_;
+    ErrorCode errorCode_;
+    HttpStatus httpStatus_;
     std::string custom_;
 
+    static HttpStatus ConvertToHttpStatus(ErrorCode code);
+
   public:
-    static const char* GetDescription(ErrorCode error);
-
     OrthancException(const char* custom) : 
-      error_(ErrorCode_Custom),
+      errorCode_(ErrorCode_Custom),
+      httpStatus_(HttpStatus_500_InternalServerError),
       custom_(custom)
     {
     }
 
     OrthancException(const std::string& custom) : 
-      error_(ErrorCode_Custom),
+      errorCode_(ErrorCode_Custom),
+      httpStatus_(HttpStatus_500_InternalServerError),
       custom_(custom)
     {
     }
 
-    OrthancException(ErrorCode error) : error_(error)
+    OrthancException(ErrorCode errorCode);
+
+    OrthancException(ErrorCode errorCode,
+                     HttpStatus httpStatus) :
+      errorCode_(errorCode),
+      httpStatus_(httpStatus)
     {
     }
 
     ErrorCode GetErrorCode() const
     {
-      return error_;
+      return errorCode_;
+    }
+
+    HttpStatus GetHttpStatus() const
+    {
+      return httpStatus_;
     }
 
     const char* What() const;