From 6d2d63621efab57b97698ce65d223ff5b3c8de10 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Fri, 29 Mar 2019 11:22:49 -0400 Subject: [PATCH 1/3] address issue 41 --- src/copy/pvCopy.cpp | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/copy/pvCopy.cpp b/src/copy/pvCopy.cpp index 88c26a2..4f803e4 100644 --- a/src/copy/pvCopy.cpp +++ b/src/copy/pvCopy.cpp @@ -492,11 +492,43 @@ CopyNodePtr PVCopy::createStructureNodes( size_t numberRequest = requestPVStructure->getPVFields().size(); if(pvSubFieldOptions) numberRequest--; if(numberRequest>0) { - nodes->push_back(createStructureNodes( - static_pointer_cast(pvMasterField), - requestPVStructure, - static_pointer_cast(copyPVField))); - continue; + Type copyType = copyPVField->getField()->getType(); + if(copyType==epics::pvData::structure) { + nodes->push_back(createStructureNodes( + static_pointer_cast(pvMasterField), + requestPVStructure, + static_pointer_cast(copyPVField))); + continue; + } + if(numberRequest!=1) { + string val("requested field "); + val += fieldName + " does not have type structure"; + throw std::logic_error(val); + } + if(copyType==epics::pvData::union_) { + PVUnionPtr pvUnion = static_pointer_cast(pvMasterField); + std::string selectedName = pvUnion->getSelectedFieldName(); + PVFieldPtrArray const & pvFields = requestPVStructure->getPVFields(); + size_t len = pvFields.size(); + if(len!=1) { + string val("field "); + val += fieldName + " logic error on pvdatabase copy"; + throw std::logic_error(val); + } + PVFieldPtr pvRequestValue = pvFields[0]; + if(pvRequestValue) { + string requestName = pvRequestValue->getFieldName(); + if(requestName.compare(selectedName)!=0) { + string val("field "); + val += requestName + " does not match union type"; + throw std::logic_error(val); + } + } + } else { + string val("requested field "); + val += fieldName + " does not have type structure"; + throw std::logic_error(val); + } } CopyNodePtr node(new CopyNode()); node->options = pvSubFieldOptions; From 20e55d5bcaa25f45cd0a61df2738a378858a8b8a Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Sun, 31 Mar 2019 07:33:51 -0400 Subject: [PATCH 2/3] minor changes --- src/copy/pvCopy.cpp | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/copy/pvCopy.cpp b/src/copy/pvCopy.cpp index 4f803e4..7e32899 100644 --- a/src/copy/pvCopy.cpp +++ b/src/copy/pvCopy.cpp @@ -464,7 +464,13 @@ StructureConstPtr PVCopy::createStructure( fields.push_back(field); } size_t numsubfields = fields.size(); - if(numsubfields==0) return NULLStructure; + if(numsubfields==0) { + std::stringstream ss; + ss << pvFromRequest << "\n"; + string val("a requested field was not found in\n"); + val += ss.str(); + throw std::invalid_argument(val); + } return getFieldCreate()->createStructure(fieldNames, fields); } @@ -500,34 +506,45 @@ CopyNodePtr PVCopy::createStructureNodes( static_pointer_cast(copyPVField))); continue; } - if(numberRequest!=1) { - string val("requested field "); - val += fieldName + " does not have type structure"; - throw std::logic_error(val); - } if(copyType==epics::pvData::union_) { + if(numberRequest!=1) { + std::stringstream ss; + ss << pvFromRequest << "\n"; + string val("union field has more than one subfield in\n"); + val += ss.str(); + throw std::logic_error(val); + } PVUnionPtr pvUnion = static_pointer_cast(pvMasterField); std::string selectedName = pvUnion->getSelectedFieldName(); PVFieldPtrArray const & pvFields = requestPVStructure->getPVFields(); size_t len = pvFields.size(); if(len!=1) { - string val("field "); - val += fieldName + " logic error on pvdatabase copy"; - throw std::logic_error(val); + std::stringstream ss; + ss << pvFromRequest << "\n"; + string val("subfield of union has more than one subfield in\n"); + val += ss.str(); + throw std::invalid_argument(val); } PVFieldPtr pvRequestValue = pvFields[0]; if(pvRequestValue) { string requestName = pvRequestValue->getFieldName(); if(requestName.compare(selectedName)!=0) { + std::stringstream ss; + ss << pvFromRequest << "\n"; + string requestName = pvRequestValue->getFieldName(); string val("field "); - val += requestName + " does not match union type"; - throw std::logic_error(val); + val += requestName + " does not match union type in\n"; + val += ss.str(); + throw std::invalid_argument(val); } } } else { + std::stringstream ss; + ss << pvFromRequest << "\n"; string val("requested field "); - val += fieldName + " does not have type structure"; - throw std::logic_error(val); + val += fieldName + " does not have type structure in\n"; + val += ss.str(); + throw std::invalid_argument(val); } } CopyNodePtr node(new CopyNode()); From 5f42eec15a8d1d70d93999df6acd0f062cfefdf3 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Sun, 31 Mar 2019 15:38:13 -0400 Subject: [PATCH 3/3] better exception messages --- src/copy/pvCopy.cpp | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/copy/pvCopy.cpp b/src/copy/pvCopy.cpp index 7e32899..31062eb 100644 --- a/src/copy/pvCopy.cpp +++ b/src/copy/pvCopy.cpp @@ -168,7 +168,7 @@ PVFieldPtr PVCopy::getMasterPVField(size_t structureOffset) node = getMasterNode(snode,structureOffset); } if(!node) { - throw std::invalid_argument( + throw std::logic_error( "PVCopy::getMasterPVField: structureOffset not valid"); } size_t diff = structureOffset - node->structureOffset; @@ -248,7 +248,7 @@ PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset) } } if(okToContinue) continue; - throw std::invalid_argument("fieldOffset not valid"); + throw std::logic_error("PVCopy logic error: fieldOffset not valid"); } } @@ -467,7 +467,7 @@ StructureConstPtr PVCopy::createStructure( if(numsubfields==0) { std::stringstream ss; ss << pvFromRequest << "\n"; - string val("a requested field was not found in\n"); + string val("no fields from the following request were found\n"); val += ss.str(); throw std::invalid_argument(val); } @@ -493,10 +493,14 @@ CopyNodePtr PVCopy::createStructureNodes( requestPVStructure->getSubField("_options"); PVFieldPtr pvMasterField = pvMasterStructure->getSubField(fieldName); if(!pvMasterField) { - throw std::logic_error("did not find field in master"); + throw std::logic_error("PVCopy logic error: did not find field in master"); } size_t numberRequest = requestPVStructure->getPVFields().size(); - if(pvSubFieldOptions) numberRequest--; + bool haveOptions = false; + if(pvSubFieldOptions) { + numberRequest--; + haveOptions = true; + } if(numberRequest>0) { Type copyType = copyPVField->getField()->getType(); if(copyType==epics::pvData::structure) { @@ -510,27 +514,29 @@ CopyNodePtr PVCopy::createStructureNodes( if(numberRequest!=1) { std::stringstream ss; ss << pvFromRequest << "\n"; - string val("union field has more than one subfield in\n"); + string val("In the following request a union field has more than one subfield in\n"); val += ss.str(); - throw std::logic_error(val); + throw std::invalid_argument(val); } PVUnionPtr pvUnion = static_pointer_cast(pvMasterField); std::string selectedName = pvUnion->getSelectedFieldName(); PVFieldPtrArray const & pvFields = requestPVStructure->getPVFields(); size_t len = pvFields.size(); - if(len!=1) { + if(len>2 || (haveOptions && len!=2)) { std::stringstream ss; ss << pvFromRequest << "\n"; - string val("subfield of union has more than one subfield in\n"); + string val("PVCopy logic error: pvRequest is\n"); val += ss.str(); - throw std::invalid_argument(val); + throw std::logic_error(val); } - PVFieldPtr pvRequestValue = pvFields[0]; + size_t indRequestValue = 0; + if((pvFields[0]->getFieldName().compare("_options"))==0) indRequestValue = 1; + PVFieldPtr pvRequestValue = pvFields[indRequestValue]; if(pvRequestValue) { string requestName = pvRequestValue->getFieldName(); if(requestName.compare(selectedName)!=0) { std::stringstream ss; - ss << pvFromRequest << "\n"; + ss << pvFromCopy << "\n"; string requestName = pvRequestValue->getFieldName(); string val("field "); val += requestName + " does not match union type in\n"; @@ -540,9 +546,9 @@ CopyNodePtr PVCopy::createStructureNodes( } } else { std::stringstream ss; - ss << pvFromRequest << "\n"; - string val("requested field "); - val += fieldName + " does not have type structure in\n"; + ss << pvFromCopy << "\n"; + string val("requested a subfield of field "); + val += fieldName + " which does not have type structure in\n"; val += ss.str(); throw std::invalid_argument(val); }