microsoft / microsoft/BCApps

[Bug]: Error Message Management LogTestField misresolves enum captions on comma/ordinal gaps

Open
#10,082 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Team: Integrations
Dominant language
AL
Stars
683
Forks
459
Avg merge
3d 26m
Merged PRs (30d)
633

Description

Describe the issue

Codeunit 28 "Error Message Management".LogTestField(SourceVariant; SourceFieldNo; ExpectedValue) resolves the expected value's caption by position:

// ErrorMessageManagement.Codeunit.al, LogTestField(...; ExpectedValue: Variant)
if FldRef.Type() = FieldType::Option then begin
IntValue := ExpectedValue;
ExpectedValue := SelectStr(IntValue + 1, FldRef.OptionCaption());
end;

An enum field's FieldRef.Type() is Option, so this branch runs for enums too. IntValue is the expected value's ordinal, but OptionCaption for an enum is a comma-joined list that is dense over the defined values only, and any single caption may itself contain a comma. Indexing that list by ordinal + 1 is therefore wrong in two independent ways:

Ordinal gap -> runtime error. An enum with non-contiguous ordinals (e.g. 0,1,2,10) has an ordinal larger than the number of captions, so SelectStr is asked for an index past the end and throws. The collected-errors flow, whose purpose is to accumulate messages without throwing, crashes instead.

Comma in a caption -> wrong label. A caption such as 'Received, not invoiced' adds a comma to the list, shifting every later entry by one, so the rendered message names the wrong member.

The normal fallback path in the same method.. FldRef.TestField(ExpectedValue) when collection is inactive (and at line ~361) - renders the caption correctly via metadata, so a correct resolution already exists in the same procedure; only the collected-errors branch uses the positional lookup.

Expected behavior

LogTestField resolves the expected enum value's caption the same way TestField/Format do - via field/enum metadata - so it returns Omega and Received, not invoiced, and never throws.

Steps to reproduce

BC 27.1.41698.41776 (w1, OnPrem container). Minimal enum + a call through the collectible-errors API:

enum 50100 "Gap Enum"
{
value(0; Alpha) { Caption = 'Alpha'; }
value(1; Beta) { Caption = 'Beta'; }
value(2; CommaMember) { Caption = 'Received, not invoiced'; } // comma in caption
value(10; Omega) { Caption = 'Omega'; } // ordinal gap 2 -> 10
}

// table 50100 "Gap Rec" (temporary) with field(1; "Gap Value"; Enum "Gap Enum")
codeunit 50100 "Gap Repro"
{
trigger OnRun()
var
GapRec: Record "Gap Rec" temporary;
ErrorMessageMgt: Codeunit "Error Message Management";
ErrorMessageHandler: Codeunit "Error Message Handler";
ErrorContextElement: Codeunit "Error Context Element";
begin
GapRec.Init();
GapRec."Gap Value" := GapRec."Gap Value"::Alpha; // actual value differs from expected
GapRec.Insert();

    ErrorMessageMgt.Activate(ErrorMessageHandler);
    ErrorMessageMgt.PushContext(ErrorContextElement, GapRec, 0, '');

    // ordinal 2, comma caption -> renders wrong label
    ErrorMessageMgt.LogTestField(GapRec, GapRec.FieldNo("Gap Value"), GapRec."Gap Value"::CommaMember);

    // ordinal 10, gap -> throws in SelectStr
    ErrorMessageMgt.LogTestField(GapRec, GapRec.FieldNo("Gap Value"), GapRec."Gap Value"::Omega);
end;

}

Additional context

Found while testing enum caption resolution through the collectible-errors API. The attached repro is self-contained; no external app is required to reproduce.

Status: Error
Error: field OptionCaption SelectStr indexes into: "Alpha,Beta,Received, not invoiced,Omega"
correct captions: Alpha=ord0, Beta=ord1, "Received, not invoiced"=ord2, Omega=ord10

LogTestField expected=Omega (ord 10 -> SelectStr(11)): threw:

  • The SELECTSTR comma-string Alpha,Beta,Received, not invoiced,Omega does not contain a value for index 11.
  • LogTestField expected=CommaMember (ord 2 -> SelectStr(3)): logged (no throw)
  • LogTestField expected=Beta (ord 1 -> SelectStr(2), control): logged (no throw)

== collected error messages ==
Message="Gap Value must be equal to Received."
Message="Gap Value must be equal to Beta."

I will provide a fix for a bug
  • I will provide a fix for a bug

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in ErrorMessageManagement.Codeunit.al at LogTestField, focusing on the collected-errors branch and comparing it with the metadata-based fallback near line 361. Use the self-contained enum reproduction to verify captions containing commas and non-contiguous ordinals. Done means CommaMember reports “Received, not invoiced” and Omega logs without throwing.

Written by the indexing model from the issue text.

Assessment

Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.