From 0cbb3b49189901cf6d5b292fe9ef54da92ca6a95 Mon Sep 17 00:00:00 2001 From: Johannes Terblanche Date: Tue, 19 May 2026 10:31:18 +0200 Subject: [PATCH 1/2] Enhance error handling in FactorDFG and VariableDFG constructors; ensure unique variable orders and proper tag initialization --- src/entities/Factor.jl | 14 ++++++++++++++ src/entities/Variable.jl | 1 + src/services/compare.jl | 6 +++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/entities/Factor.jl b/src/entities/Factor.jl index e5af5d04..5a31f1cc 100644 --- a/src/entities/Factor.jl +++ b/src/entities/Factor.jl @@ -128,6 +128,20 @@ function FactorDFG( timestamp = TimeDateZone(timestamp.utc_datetime) end + #TODO move to core constructor + if !isempty(multihypo) && length(multihypo) != length(variableorder) + throw( + ArgumentError( + "multihypo length ($(length(multihypo))) must match the number of variables ($(length(variableorder))). " * + "See fractional data-association uncertainty docs.", + ), + ) + end + if length(variableorder) == 1 && observation isa AbstractRelativeObservation + throw(ArgumentError("Relative observation $(typeof(observation)) requires at least two variables, but only one was provided: $variableorder. Use a subtype of AbstractPriorObservation for single-variable factors.")) + end + allunique(variableorder) || throw(ArgumentError("Variable order must be unique, got duplicates in $variableorder")) + # create factor data hyper = Recipehyper(; multihypo, nullhypo, inflation) state = Recipestate() diff --git a/src/entities/Variable.jl b/src/entities/Variable.jl index 71e22328..b4d18ca6 100644 --- a/src/entities/Variable.jl +++ b/src/entities/Variable.jl @@ -124,6 +124,7 @@ function VariableDFG( if solvable isa Int solvable = Ref(solvable) end + tags = tags isa Set ? tags : Set{Symbol}(tags) union!(tags, [:VARIABLE]) P = getPointType(T) diff --git a/src/services/compare.jl b/src/services/compare.jl index 20a25a68..33ee3b7b 100644 --- a/src/services/compare.jl +++ b/src/services/compare.jl @@ -215,7 +215,11 @@ function compareVariable( union!(skiplist, skip) # TP = TP && compareAll(A.states, B.states; skip = skiplist, show = show) - Ad = getState(A, :default) #FIXME why onlly comparing default? + #FIXME why only comparing hardcoded default? + if !hasState(A, :default) && !hasState(B, :default) + return false + end + Ad = getState(A, :default) Bd = getState(B, :default) # TP = TP && compareAll(A.attributes, B.attributes, skip=[:variableType;], show=show) From aed72dd7aa2718879e1feeb0b2f0d1a06626d1ab Mon Sep 17 00:00:00 2001 From: Johannes Terblanche Date: Tue, 19 May 2026 10:33:32 +0200 Subject: [PATCH 2/2] format --- src/entities/Factor.jl | 10 ++++++++-- src/services/compare.jl | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/entities/Factor.jl b/src/entities/Factor.jl index 5a31f1cc..843fb09e 100644 --- a/src/entities/Factor.jl +++ b/src/entities/Factor.jl @@ -138,9 +138,15 @@ function FactorDFG( ) end if length(variableorder) == 1 && observation isa AbstractRelativeObservation - throw(ArgumentError("Relative observation $(typeof(observation)) requires at least two variables, but only one was provided: $variableorder. Use a subtype of AbstractPriorObservation for single-variable factors.")) + throw( + ArgumentError( + "Relative observation $(typeof(observation)) requires at least two variables, but only one was provided: $variableorder. Use a subtype of AbstractPriorObservation for single-variable factors.", + ), + ) end - allunique(variableorder) || throw(ArgumentError("Variable order must be unique, got duplicates in $variableorder")) + allunique(variableorder) || throw( + ArgumentError("Variable order must be unique, got duplicates in $variableorder"), + ) # create factor data hyper = Recipehyper(; multihypo, nullhypo, inflation) diff --git a/src/services/compare.jl b/src/services/compare.jl index 33ee3b7b..6d6516ac 100644 --- a/src/services/compare.jl +++ b/src/services/compare.jl @@ -219,7 +219,7 @@ function compareVariable( if !hasState(A, :default) && !hasState(B, :default) return false end - Ad = getState(A, :default) + Ad = getState(A, :default) Bd = getState(B, :default) # TP = TP && compareAll(A.attributes, B.attributes, skip=[:variableType;], show=show)