Error tracking in indirect expressions - ObjectVision/GeoDMS GitHub Wiki

If there is an error in evaluating an indirect expression, it is difficult to find what the error is, especially in complex long expressions.

For example the following error from evaluating the indirect expression displayed below.

FailReason  iif Error: Cannot find operator for these arguments:
arg1 of type DataItem<Bool>
arg2 of type DataItem<String>
arg3 of type DataItem<Float32>
Possible cause: argument type mismatch. Check the types of the used arguments.
attribute<Woning> Restclaim0 (AllocRegio) := =
    FirstSeqIndicator && FirstIterIndicator && FirstExtentIndicator
        ? ClaimSrc_Wonen
        : FirstSeqIndicator && FirstIterIndicator && !FirstExtentIndicator
            ? 'PerExtent/'+PrevExtent+'/Restclaim0 - PerExtent/'+PrevExtent+'/Netto_woningbouw/OverExtents/Per_AllocRegio'
            : FirstSeqIndicator && !FirstIterIndicator&& FirstExtentIndicator
                ? PrevIter+'/PerExtent/'+LastExtentName+'/Restclaim0 - '+PrevIter+'/PerExtent/'+LastExtentName+'/Netto_woningbouw/OverExtents/Per_AllocRegio'
                : FirstSeqIndicator && !FirstIterIndicator && !FirstExtentIndicator
                    ? 'PerExtent/'+PrevExtent+'/Restclaim0 - PerExtent/'+PrevExtent+'/Netto_woningbouw/OverExtents/Per_AllocRegio'
                    : !FirstSeqIndicator && FirstIterIndicator && FirstExtentIndicator
                        ? 'PerAllocatieSequence/'+PrevSeq+'/DisplacedWonenDoorWerken/DisplacedWonen_perAllocRegio'
                        : !FirstSeqIndicator && FirstIterIndicator && !FirstExtentIndicator
                            ? 'PerExtent/'+PrevExtent+'/Restclaim0 - PerExtent/'+PrevExtent+'/Netto_woningbouw/OverExtents/Per_AllocRegio'
                            : !FirstSeqIndicator && !FirstIterIndicator && FirstExtentIndicator
                                ? PrevIter+'/PerExtent/'+LastExtentName+'/Restclaim0 - '+PrevIter+'/PerExtent/'+LastExtentName+'/Netto_woningbouw/OverExtents/Per_AllocRegio'
                                : !FirstSeqIndicator && !FirstIterIndicator && !FirstExtentIndicator
                                    ? 'PerExtent/'+PrevExtent+'/Restclaim0 - PerExtent/'+PrevExtent+'/Netto_woningbouw/OverExtents/Per_AllocRegio'
                                    : const(0[woning],AllocRegio);

Here the error is that _"const(0[woning],AllocRegio)" _is not between single quotes, but it can't be seen from the error dialog.

a more readable and debuggable form

Two practices make such an expression easier to read and to debug (see also Indirect-expression > readability and debugging):

  1. Lift the indirect expression into its own string parameter, so the generated direct expression can be inspected in the GeoDMS GUI, Detail Page > General, before it is evaluated.
  2. Replace the deeply nested ?: by a switchcase with one case per line, so each branch can be read and checked on its own.

Applied to the example above (with the bug already fixed):

parameter<string> Restclaim0_expr :=
    switch(
        case(FirstSeqIndicator  && FirstIterIndicator  && FirstExtentIndicator , ClaimSrc_Wonen),
        case(FirstSeqIndicator  && FirstIterIndicator  && !FirstExtentIndicator, 'PerExtent/'+PrevExtent+'/Restclaim0 - PerExtent/'+PrevExtent+'/Netto_woningbouw/OverExtents/Per_AllocRegio'),
        case(FirstSeqIndicator  && !FirstIterIndicator && FirstExtentIndicator , PrevIter+'/PerExtent/'+LastExtentName+'/Restclaim0 - '+PrevIter+'/PerExtent/'+LastExtentName+'/Netto_woningbouw/OverExtents/Per_AllocRegio'),
        case(FirstSeqIndicator  && !FirstIterIndicator && !FirstExtentIndicator, 'PerExtent/'+PrevExtent+'/Restclaim0 - PerExtent/'+PrevExtent+'/Netto_woningbouw/OverExtents/Per_AllocRegio'),
        case(!FirstSeqIndicator && FirstIterIndicator  && FirstExtentIndicator , 'PerAllocatieSequence/'+PrevSeq+'/DisplacedWonenDoorWerken/DisplacedWonen_perAllocRegio'),
        case(!FirstSeqIndicator && FirstIterIndicator  && !FirstExtentIndicator, 'PerExtent/'+PrevExtent+'/Restclaim0 - PerExtent/'+PrevExtent+'/Netto_woningbouw/OverExtents/Per_AllocRegio'),
        case(!FirstSeqIndicator && !FirstIterIndicator && FirstExtentIndicator , PrevIter+'/PerExtent/'+LastExtentName+'/Restclaim0 - '+PrevIter+'/PerExtent/'+LastExtentName+'/Netto_woningbouw/OverExtents/Per_AllocRegio'),
        'const(0[woning], AllocRegio)'  // default
    );

attribute<Woning> Restclaim0 (AllocRegio) := =Restclaim0_expr;

Laid out this way the bug is easy to spot. Every branch of an indirect expression must evaluate to a string — a fragment of the generated direct expression. All branches above do: the quoted path literals, the concatenations, and the string parameter ClaimSrc_Wonen (the error reports arg2 to be of type String, confirming this). The only exception was the default, which in the original read const(0[woning],AllocRegio) without quotes and therefore evaluated to a Woning attribute rather than a string — exactly the arg2 of type String versus arg3 of type Float32 mismatch from the error dialog. Putting it between single quotes, 'const(0[woning], AllocRegio)', turns it into a string fragment like the other branches and resolves the error.

Because the calculation rule of Restclaim0 is now simply =Restclaim0_expr, the evaluated string is also available for inspection on Restclaim0_expr itself, which makes locating such mistakes much easier than reading them from the error dialog.

⚠️ **GitHub.com Fallback** ⚠️