diff --git a/src/complex/Pipeline/Pipeline.cpp b/src/complex/Pipeline/Pipeline.cpp index fa8f8d2c56..8ad65963cf 100644 --- a/src/complex/Pipeline/Pipeline.cpp +++ b/src/complex/Pipeline/Pipeline.cpp @@ -859,10 +859,14 @@ Result Pipeline::FromSIMPLJson(const nlohmann::json& json, FilterList* if(filterResult.invalid()) { - return ConvertInvalidResult(std::move(filterResult)); + auto pipelineFilter = std::make_unique(nullptr); + pipelineFilter->setComments(PipelineFilter::CreateErrorComments(filterResult.errors(), "Filter conversion error: ")); + pipeline.push_back(std::move(pipelineFilter)); + } + else + { + pipeline.push_back(std::move(filterResult.value())); } - - pipeline.push_back(std::move(filterResult.value())); } return {std::move(pipeline)}; diff --git a/src/complex/Pipeline/PipelineFilter.cpp b/src/complex/Pipeline/PipelineFilter.cpp index a00797794f..b5ae23a3bb 100644 --- a/src/complex/Pipeline/PipelineFilter.cpp +++ b/src/complex/Pipeline/PipelineFilter.cpp @@ -18,8 +18,10 @@ constexpr StringLiteral k_FilterKey = "filter"; constexpr StringLiteral k_FilterNameKey = "name"; constexpr StringLiteral k_FilterUuidKey = "uuid"; constexpr StringLiteral k_FilterCommentsKey = "comments"; +constexpr StringLiteral k_UnknownFilterValue = "UnknownFilter"; constexpr StringLiteral k_SIMPLFilterUuidKey = "Filter_Uuid"; +constexpr StringLiteral k_SIMPLFilterHumanNameKey = "Filter_Human_Label"; nlohmann::json CreateFilterJson(std::string_view uuid, std::string_view name, nlohmann::json argsArray, std::string_view comments) { @@ -155,8 +157,16 @@ bool PipelineFilter::preflight(DataStructure& data, RenamedPaths& renamedPaths, IFilter::MessageHandler messageHandler{[this](const IFilter::Message& message) { this->notifyFilterMessage(message); }}; clearFaultState(); - IFilter::PreflightResult result = m_Filter->preflight(data, getArguments(), messageHandler, shouldCancel); - m_Warnings = std::move(result.outputActions.warnings()); + IFilter::PreflightResult result; + if(m_Filter != nullptr) + { + result = m_Filter->preflight(data, getArguments(), messageHandler, shouldCancel); + m_Warnings = std::move(result.outputActions.warnings()); + } + else + { + m_Warnings.push_back(Warning{-10, "This filter is just a placeholder! The original filter could not be found. See the filter comments for more details."}); + } setHasWarnings(!m_Warnings.empty()); m_PreflightValues = std::move(result.outputValues); if(result.outputActions.invalid()) @@ -241,10 +251,18 @@ bool PipelineFilter::execute(DataStructure& data, const std::atomic_bool& should IFilter::MessageHandler messageHandler{[this](const IFilter::Message& message) { this->notifyFilterMessage(message); }}; - IFilter::ExecuteResult result = m_Filter->execute(data, getArguments(), this, messageHandler, shouldCancel); - m_PreflightValues = std::move(result.outputValues); + IFilter::ExecuteResult result; + if(m_Filter != nullptr) + { + result = m_Filter->execute(data, getArguments(), this, messageHandler, shouldCancel); + m_Warnings = result.result.warnings(); + } + else + { + m_Warnings.push_back(Warning{-11, "This filter is just a placeholder! The original filter could not be found. See the filter comments for more details."}); + } - m_Warnings = result.result.warnings(); + m_PreflightValues = std::move(result.outputValues); if(result.result.invalid()) { @@ -444,7 +462,7 @@ const std::vector& PipelineFilter::getPreflightValues() std::unique_ptr PipelineFilter::deepCopy() const { - return std::make_unique(m_Filter->clone(), m_Arguments); + return m_Filter == nullptr ? std::make_unique(nullptr, m_Arguments) : std::make_unique(m_Filter->clone(), m_Arguments); } void PipelineFilter::notifyFilterMessage(const IFilter::Message& message) @@ -478,6 +496,10 @@ void PipelineFilter::notifyRenamedPaths(const RenamedPaths& renamedPathPairs) nlohmann::json PipelineFilter::toJsonImpl() const { + if(m_Filter == nullptr) + { + return CreateFilterJson("", k_UnknownFilterValue, nlohmann::json{}, m_Comments); + } return CreateFilterJson(m_Filter->uuid().str(), m_Filter->name(), m_Filter->toJson(m_Arguments), m_Comments); } @@ -511,7 +533,24 @@ Result> PipelineFilter::FromJson(const nlohmann: { return MakeErrorResult>(-3, "UUID value is not a string"); } + + const bool isDisabled = ReadDisabledState(json); + std::string comments; + if(json.contains(k_FilterCommentsKey.view())) + { + comments = json[k_FilterCommentsKey]; + } auto filterName = filterNameObject.get(); + + if(filterName == k_UnknownFilterValue) + { + auto pipelineFilter = std::make_unique(nullptr); + pipelineFilter->setDisabled(isDisabled); + pipelineFilter->setComments(comments); + Result> result{std::move(pipelineFilter)}; + return result; + } + auto uuidString = uuidObject.get(); std::optional uuid = Uuid::FromString(uuidString); if(!uuid.has_value()) @@ -530,8 +569,6 @@ Result> PipelineFilter::FromJson(const nlohmann: } const auto& argsJson = json[k_ArgsKey]; - const bool isDisabled = ReadDisabledState(json); - auto argsResult = filter->fromJson(argsJson); if(argsResult.invalid()) @@ -543,12 +580,7 @@ Result> PipelineFilter::FromJson(const nlohmann: auto pipelineFilter = std::make_unique(std::move(filter), std::move(argsResult.value())); pipelineFilter->setDisabled(isDisabled); - - if(json.contains(k_FilterCommentsKey.view())) - { - pipelineFilter->setComments(json[k_FilterCommentsKey]); - } - + pipelineFilter->setComments(comments); Result> result{std::move(pipelineFilter)}; result.warnings() = std::move(argsResult.warnings()); return result; @@ -605,14 +637,13 @@ complex::WarningCollection convertErrors(const complex::ErrorCollection& errors, return std::move(warnings); } -std::string createErrorComments(const complex::ErrorCollection& errors, const std::string& filterName) +std::string PipelineFilter::CreateErrorComments(const complex::ErrorCollection& errors, const std::string& prefix) { if(errors.empty()) { return ""; } - std::string prefix = "Parameter conversion error: "; std::string output; for(const auto& error : errors) { @@ -640,7 +671,12 @@ Result> PipelineFilter::FromSIMPLJson(const nloh if(!simplData.has_value()) { - return MakeErrorResult>(-3, fmt::format("Unable to parse find conversion data for filter '{}'", uuidString)); + std::string filterName = fmt::format("with uuid {}", uuidString); + if(json.contains(k_SIMPLFilterHumanNameKey)) + { + filterName = fmt::format("{} with uuid {}", json[k_SIMPLFilterHumanNameKey].get(), uuidString); + } + return MakeErrorResult>(-3, fmt::format("Unable to find conversion data for filter '{}'", filterName)); } IFilter::UniquePointer filter = filterList.createFilter(simplData->complexUuid); @@ -668,7 +704,7 @@ Result> PipelineFilter::FromSIMPLJson(const nloh if(argumentsResult.invalid()) { warnings = convertErrors(argumentsResult.errors(), filterName); - pipelineFilter->setComments(createErrorComments(argumentsResult.errors(), filterName)); + pipelineFilter->setComments(CreateErrorComments(argumentsResult.errors(), "Parameter conversion error: ")); } return {std::move(pipelineFilter), std::move(warnings)}; diff --git a/src/complex/Pipeline/PipelineFilter.hpp b/src/complex/Pipeline/PipelineFilter.hpp index fba41defa6..1afc51c7fb 100644 --- a/src/complex/Pipeline/PipelineFilter.hpp +++ b/src/complex/Pipeline/PipelineFilter.hpp @@ -57,6 +57,14 @@ class COMPLEX_EXPORT PipelineFilter : public AbstractPipelineNode */ static Result> FromSIMPLJson(const nlohmann::json& json, const FilterList& filterList); + /** + * @brief Creates a comment string from the errors collection + * @param errors The errors to convert to strings for storing in a comment + * @param prefix The comment string prefix for each of the errors + * @return The converted comment string containing all of the errors + */ + static std::string CreateErrorComments(const complex::ErrorCollection& errors, const std::string& prefix); + /** * @brief Constructs a PipelineFilter with the provided filter and arguments. * If no Arguments are provided, a default empty value will be used instead.