changeset 1734:e2675b37eb01

Under Windows, the exit status of Orthanc corresponds to the encountered error code
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 21 Oct 2015 14:28:57 +0200
parents e1f5ab395297
children a001f6226c7c
files NEWS OrthancServer/main.cpp Resources/GenerateErrorCodes.py
diffstat 3 files changed, 111 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Wed Oct 21 14:10:55 2015 +0200
+++ b/NEWS	Wed Oct 21 14:28:57 2015 +0200
@@ -28,7 +28,9 @@
 * "/system" URI gives information about the plugins used for storage area and DB back-end
 * Plugin callbacks should now return explicit "OrthancPluginErrorCode" instead of integers
 * "/tools/create-dicom" can create tags with unknown VR
-* "--logdir" creates a single log file instead of 3 separate files for errors/warnings/infos
+* "--logdir" flag creates a single log file instead of 3 separate files for errors/warnings/infos
+* "--errors" flag lists the error codes that could be returned by Orthanc
+* Under Windows, the exit status of Orthanc corresponds to the encountered error code
 
 
 Version 0.9.4 (2015/09/16)
--- a/OrthancServer/main.cpp	Wed Oct 21 14:10:55 2015 +0200
+++ b/OrthancServer/main.cpp	Wed Oct 21 14:28:57 2015 +0200
@@ -449,13 +449,105 @@
 {
   std::cout
     << path << " " << ORTHANC_VERSION << std::endl
-    << "Orthanc, lightweight, RESTful DICOM server for healthcare and medical research." << std::endl
-    << "List of error codes that could be returned by Orthanc:" << std::endl << std::endl;
+    << "Orthanc, lightweight, RESTful DICOM server for healthcare and medical research." 
+    << std::endl << std::endl
+    << "List of error codes that could be returned by Orthanc:" 
+    << std::endl << std::endl;
 
   // The content of the following brackets is automatically generated
   // by the "GenerateErrorCodes.py" script
   {
-    PrintErrorCode(ErrorCode_BadFileFormat, "tutu");
+    PrintErrorCode(ErrorCode_InternalError, "Internal error");
+    PrintErrorCode(ErrorCode_Success, "Success");
+    PrintErrorCode(ErrorCode_Plugin, "Error encountered within the plugin engine");
+    PrintErrorCode(ErrorCode_NotImplemented, "Not implemented yet");
+    PrintErrorCode(ErrorCode_ParameterOutOfRange, "Parameter out of range");
+    PrintErrorCode(ErrorCode_NotEnoughMemory, "Not enough memory");
+    PrintErrorCode(ErrorCode_BadParameterType, "Bad type for a parameter");
+    PrintErrorCode(ErrorCode_BadSequenceOfCalls, "Bad sequence of calls");
+    PrintErrorCode(ErrorCode_InexistentItem, "Accessing an inexistent item");
+    PrintErrorCode(ErrorCode_BadRequest, "Bad request");
+    PrintErrorCode(ErrorCode_NetworkProtocol, "Error in the network protocol");
+    PrintErrorCode(ErrorCode_SystemCommand, "Error while calling a system command");
+    PrintErrorCode(ErrorCode_Database, "Error with the database engine");
+    PrintErrorCode(ErrorCode_UriSyntax, "Badly formatted URI");
+    PrintErrorCode(ErrorCode_InexistentFile, "Inexistent file");
+    PrintErrorCode(ErrorCode_CannotWriteFile, "Cannot write to file");
+    PrintErrorCode(ErrorCode_BadFileFormat, "Bad file format");
+    PrintErrorCode(ErrorCode_Timeout, "Timeout");
+    PrintErrorCode(ErrorCode_UnknownResource, "Unknown resource");
+    PrintErrorCode(ErrorCode_IncompatibleDatabaseVersion, "Incompatible version of the database");
+    PrintErrorCode(ErrorCode_FullStorage, "The file storage is full");
+    PrintErrorCode(ErrorCode_CorruptedFile, "Corrupted file (e.g. inconsistent MD5 hash)");
+    PrintErrorCode(ErrorCode_InexistentTag, "Inexistent tag");
+    PrintErrorCode(ErrorCode_ReadOnly, "Cannot modify a read-only data structure");
+    PrintErrorCode(ErrorCode_IncompatibleImageFormat, "Incompatible format of the images");
+    PrintErrorCode(ErrorCode_IncompatibleImageSize, "Incompatible size of the images");
+    PrintErrorCode(ErrorCode_SharedLibrary, "Error while using a shared library (plugin)");
+    PrintErrorCode(ErrorCode_UnknownPluginService, "Plugin invoking an unknown service");
+    PrintErrorCode(ErrorCode_UnknownDicomTag, "Unknown DICOM tag");
+    PrintErrorCode(ErrorCode_BadJson, "Cannot parse a JSON document");
+    PrintErrorCode(ErrorCode_Unauthorized, "Bad credentials were provided to an HTTP request");
+    PrintErrorCode(ErrorCode_BadFont, "Badly formatted font file");
+    PrintErrorCode(ErrorCode_DatabasePlugin, "The plugin implementing a custom database back-end does not fulfill the proper interface");
+    PrintErrorCode(ErrorCode_StorageAreaPlugin, "Error in the plugin implementing a custom storage area");
+    PrintErrorCode(ErrorCode_SQLiteNotOpened, "SQLite: The database is not opened");
+    PrintErrorCode(ErrorCode_SQLiteAlreadyOpened, "SQLite: Connection is already open");
+    PrintErrorCode(ErrorCode_SQLiteCannotOpen, "SQLite: Unable to open the database");
+    PrintErrorCode(ErrorCode_SQLiteStatementAlreadyUsed, "SQLite: This cached statement is already being referred to");
+    PrintErrorCode(ErrorCode_SQLiteExecute, "SQLite: Cannot execute a command");
+    PrintErrorCode(ErrorCode_SQLiteRollbackWithoutTransaction, "SQLite: Rolling back a nonexistent transaction (have you called Begin()?)");
+    PrintErrorCode(ErrorCode_SQLiteCommitWithoutTransaction, "SQLite: Committing a nonexistent transaction");
+    PrintErrorCode(ErrorCode_SQLiteRegisterFunction, "SQLite: Unable to register a function");
+    PrintErrorCode(ErrorCode_SQLiteFlush, "SQLite: Unable to flush the database");
+    PrintErrorCode(ErrorCode_SQLiteCannotRun, "SQLite: Cannot run a cached statement");
+    PrintErrorCode(ErrorCode_SQLiteCannotStep, "SQLite: Cannot step over a cached statement");
+    PrintErrorCode(ErrorCode_SQLiteBindOutOfRange, "SQLite: Bing a value while out of range (serious error)");
+    PrintErrorCode(ErrorCode_SQLitePrepareStatement, "SQLite: Cannot prepare a cached statement");
+    PrintErrorCode(ErrorCode_SQLiteTransactionAlreadyStarted, "SQLite: Beginning the same transaction twice");
+    PrintErrorCode(ErrorCode_SQLiteTransactionCommit, "SQLite: Failure when committing the transaction");
+    PrintErrorCode(ErrorCode_SQLiteTransactionBegin, "SQLite: Cannot start a transaction");
+    PrintErrorCode(ErrorCode_DirectoryOverFile, "The directory to be created is already occupied by a regular file");
+    PrintErrorCode(ErrorCode_FileStorageCannotWrite, "Unable to create a subdirectory or a file in the file storage");
+    PrintErrorCode(ErrorCode_DirectoryExpected, "The specified path does not point to a directory");
+    PrintErrorCode(ErrorCode_HttpPortInUse, "The TCP port of the HTTP server is already in use");
+    PrintErrorCode(ErrorCode_DicomPortInUse, "The TCP port of the DICOM server is already in use");
+    PrintErrorCode(ErrorCode_BadHttpStatusInRest, "This HTTP status is not allowed in a REST API");
+    PrintErrorCode(ErrorCode_RegularFileExpected, "The specified path does not point to a regular file");
+    PrintErrorCode(ErrorCode_PathToExecutable, "Unable to get the path to the executable");
+    PrintErrorCode(ErrorCode_MakeDirectory, "Cannot create a directory");
+    PrintErrorCode(ErrorCode_BadApplicationEntityTitle, "An application entity title (AET) cannot be empty or be longer than 16 characters");
+    PrintErrorCode(ErrorCode_NoCFindHandler, "No request handler factory for DICOM C-FIND SCP");
+    PrintErrorCode(ErrorCode_NoCMoveHandler, "No request handler factory for DICOM C-MOVE SCP");
+    PrintErrorCode(ErrorCode_NoCStoreHandler, "No request handler factory for DICOM C-STORE SCP");
+    PrintErrorCode(ErrorCode_NoApplicationEntityFilter, "No application entity filter");
+    PrintErrorCode(ErrorCode_NoSopClassOrInstance, "DicomUserConnection: Unable to find the SOP class and instance");
+    PrintErrorCode(ErrorCode_NoPresentationContext, "DicomUserConnection: No acceptable presentation context for modality");
+    PrintErrorCode(ErrorCode_DicomFindUnavailable, "DicomUserConnection: The C-FIND command is not supported by the remote SCP");
+    PrintErrorCode(ErrorCode_DicomMoveUnavailable, "DicomUserConnection: The C-MOVE command is not supported by the remote SCP");
+    PrintErrorCode(ErrorCode_CannotStoreInstance, "Cannot store an instance");
+    PrintErrorCode(ErrorCode_CreateDicomNotString, "Only string values are supported when creating DICOM instances");
+    PrintErrorCode(ErrorCode_CreateDicomOverrideTag, "Trying to override a value inherited from a parent module");
+    PrintErrorCode(ErrorCode_CreateDicomUseContent, "Use \"Content\" to inject an image into a new DICOM instance");
+    PrintErrorCode(ErrorCode_CreateDicomNoPayload, "No payload is present for one instance in the series");
+    PrintErrorCode(ErrorCode_CreateDicomUseDataUriScheme, "The payload of the DICOM instance must be specified according to Data URI scheme");
+    PrintErrorCode(ErrorCode_CreateDicomBadParent, "Trying to attach a new DICOM instance to an inexistent resource");
+    PrintErrorCode(ErrorCode_CreateDicomParentIsInstance, "Trying to attach a new DICOM instance to an instance (must be a series, study or patient)");
+    PrintErrorCode(ErrorCode_CreateDicomParentEncoding, "Unable to get the encoding of the parent resource");
+    PrintErrorCode(ErrorCode_UnknownModality, "Unknown modality");
+    PrintErrorCode(ErrorCode_BadJobOrdering, "Bad ordering of filters in a job");
+    PrintErrorCode(ErrorCode_JsonToLuaTable, "Cannot convert the given JSON object to a Lua table");
+    PrintErrorCode(ErrorCode_CannotCreateLua, "Cannot create the Lua context");
+    PrintErrorCode(ErrorCode_CannotExecuteLua, "Cannot execute a Lua command");
+    PrintErrorCode(ErrorCode_LuaAlreadyExecuted, "Arguments cannot be pushed after the Lua function is executed");
+    PrintErrorCode(ErrorCode_LuaBadOutput, "The Lua function does not give the expected number of outputs");
+    PrintErrorCode(ErrorCode_NotLuaPredicate, "The Lua function is not a predicate (only true/false outputs allowed)");
+    PrintErrorCode(ErrorCode_LuaReturnsNoString, "The Lua function does not return a string");
+    PrintErrorCode(ErrorCode_StorageAreaAlreadyRegistered, "Another plugin has already registered a custom storage area");
+    PrintErrorCode(ErrorCode_DatabaseBackendAlreadyRegistered, "Another plugin has already registered a custom database back-end");
+    PrintErrorCode(ErrorCode_DatabaseNotInitialized, "Plugin trying to call the database during its initialization");
+    PrintErrorCode(ErrorCode_SslDisabled, "Orthanc has been built without SSL support");
+    PrintErrorCode(ErrorCode_CannotOrderSlices, "Unable to order the slices of the series");
   }
 
   std::cout << std::endl;
@@ -975,7 +1067,15 @@
   {
     LOG(ERROR) << "Uncaught exception, stopping now: [" << e.What() << "] (code " << e.GetErrorCode() << ")";
 #if defined(_WIN32)
-    status = static_cast<int>(e.GetErrorCode());
+    if (e.GetErrorCode() >= ErrorCode_START_PLUGINS)
+    {
+      status = static_cast<int>(ErrorCode_Plugin);
+    }
+    else
+    {
+      status = static_cast<int>(e.GetErrorCode());
+    }
+
 #else
     status = -1;
 #endif
--- a/Resources/GenerateErrorCodes.py	Wed Oct 21 14:10:55 2015 +0200
+++ b/Resources/GenerateErrorCodes.py	Wed Oct 21 14:28:57 2015 +0200
@@ -152,9 +152,8 @@
 with open(path, 'r') as f:
     a = f.read()
 
-s = '\n'.join(map(lambda x: '    PrintError(%d, "%s");' % (x['Code'], x['Name']), ERRORS))
+s = '\n'.join(map(lambda x: '    PrintErrorCode(ErrorCode_%s, "%s");' % (x['Name'], x['Description']), ERRORS))
+a = re.sub('(static void PrintErrors[^{}]*?{[^{}]*?{)([^}]*?)}', r'\1\n%s\n  }' % s, a, re.DOTALL)
 
-print s
-
-#with open(path, 'w') as f:
-#    f.write(a)
+with open(path, 'w') as f:
+    f.write(a)