From cde6b7727b47c28e0a7a6213a44ad4136a7bf5d8 Mon Sep 17 00:00:00 2001
From: Martin Hierholzer <martin.hierholzer@desy.de>
Date: Thu, 11 Jan 2018 15:51:58 +0100
Subject: [PATCH] Do not stop server (even through assert -> undefined
 behaviour without Debug flags!) when trying to create a string array. Instead
 the property is simply ignored and a warning is printed.

---
 src/CSAdapterEqFct.cc | 16 +++++++++++-----
 src/DoocsPVFactory.cc | 11 +++++++++--
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/src/CSAdapterEqFct.cc b/src/CSAdapterEqFct.cc
index 4914d6a..d968be4 100644
--- a/src/CSAdapterEqFct.cc
+++ b/src/CSAdapterEqFct.cc
@@ -6,22 +6,22 @@
 namespace ChimeraTK{
 
   bool CSAdapterEqFct::emptyLocationVariablesHandled = false;
-  
+
 
   CSAdapterEqFct::CSAdapterEqFct(int fctCode,
     boost::shared_ptr<ControlSystemPVManager> const & controlSystemPVManager,
     boost::shared_ptr<DoocsUpdater> const & updater, std::string fctName )
     // The second argument in EqFct has to be a pointer to string, and NULL pointer is
     // used when the name is coming from the config file. This interface is so ugly that
-    // I changed it to std::string and need the ?: trick to get a NULL pointer in 
+    // I changed it to std::string and need the ?: trick to get a NULL pointer in
     // if the string is empty
     : EqFct ("NAME = CSAdapterEqFct", fctName.empty()?NULL:&fctName),
      controlSystemPVManager_(controlSystemPVManager),
       fctCode_(fctCode), updater_(updater){
-    
+
     registerProcessVariablesInDoocs();
   }
-  
+
   CSAdapterEqFct::~CSAdapterEqFct(){
     //stop the updater thread before any of the process variables go out of scope
     updater_->stop();
@@ -43,7 +43,13 @@ namespace ChimeraTK{
     doocsProperties_.reserve( mappingForThisLocation.size() );
 
     for (auto & propertyDescrition : mappingForThisLocation){
-      doocsProperties_.push_back( factory.create( propertyDescrition ) );
+      try {
+        doocsProperties_.push_back( factory.create( propertyDescrition ) );
+      }
+      catch(std::invalid_argument &e) {
+        std::cerr << "**** WARNING: Could not create property for variable '" << propertyDescrition->location << "/" <<
+                     propertyDescrition->name << "': " << e.what() << ". Skipping this property." << std::endl;
+      }
     }
   }
 
diff --git a/src/DoocsPVFactory.cc b/src/DoocsPVFactory.cc
index a248fdf..da483b3 100644
--- a/src/DoocsPVFactory.cc
+++ b/src/DoocsPVFactory.cc
@@ -170,8 +170,9 @@ namespace ChimeraTK {
     } else if (valueType == typeid(double)) {
       return typedCreateScalarOrArray<double, D_double, double, D_doublearray, double>(*processVariable, *autoPropertyDescription, DecoratorType::range_checking, ArrayDescription::DataType::Double);
     } else if (valueType == typeid(std::string)) {
-      //@todo FIXME returning scalar also for arrays. This should result in an error
-      return createDoocsScalar<std::string, D_string>(*autoPropertyDescription, DecoratorType::range_checking);
+      return typedCreateScalarOrArray<std::string, D_string, std::string,
+                                      std::nullptr_t, std::nullptr_t>(*processVariable, *autoPropertyDescription,
+                                                                      DecoratorType::range_checking, ArrayDescription::DataType::Auto);
     } else {
       throw std::invalid_argument("unsupported value type");
     }
@@ -194,6 +195,12 @@ namespace ChimeraTK {
     return doocsPV;
   }
 
+  // template specialisation for cases with no matching DOOCS array type (e.g. string)
+  template<>
+  boost::shared_ptr<D_fct> DoocsPVFactory::typedCreateDoocsArray<std::nullptr_t,std::nullptr_t>(ArrayDescription const &){
+    throw std::invalid_argument("Type not supported as an array");
+  }
+
   boost::shared_ptr<D_fct>  DoocsPVFactory::createDoocsArray(  std::shared_ptr<ArrayDescription> const & arrayDescription){
     if(arrayDescription->dataType == ArrayDescription::DataType::Auto){
       // leave the desision which array to produce to the auto creation algorithm. We need it there anyway
-- 
GitLab