microsoft / microsoft/AL

AA0136 does not flag unreachable code after `Record.FieldError(...)`, although it does after `Error(...)`

Open
#8,324 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

accepted CodeCop
Dominant language
PowerShell
Stars
881
Forks
285
Avg merge
3d 36m
Merged PRs (30d)
1

Description

1. Describe the bug

CodeCop rule AA0136 (Do not write code that will never be hit) detects unreachable code after a built-in Error(...) call, but not after Record.FieldError(...) or FieldRef.FieldError(...), even though both unconditionally stop the execution of AL code.

The official documentation describes both methods with the same terminal semantics:

  • Dialog.Error: "Displays an error message and ends the execution of AL code."
  • Record.FieldError / FieldRef.FieldError: "Stops the execution of the code, causing a run-time error, and creates an error message for a field."

Since FieldError is the idiomatic way to raise a field-specific validation error, dead code following it goes undetected, while the semantically identical Error(...) pattern is flagged.

2. To Reproduce

Steps to reproduce the behavior:

  1. Create an AL project with CodeCop enabled ("al.codeAnalyzers": ["${CodeCop}"]).
  2. Add the codeunit below and observe the AA0136 diagnostics.
codeunit 50100 "AA0136 FieldError Repro"
{
    local procedure DemoUnreachable(SalesLine: Record "Sales Line")
    begin
        SalesLine.FieldError(Type);
        Message('Unreachable'); // NOT flagged by AA0136 - but this code can never run

        Error('Stop');
        Message('Unreachable'); // IS flagged by AA0136
    end;
}

3. Expected behavior

AA0136 is reported on both Message(...) statements: a statement directly following an unconditional FieldError(...) call can never be hit, exactly like one following Error(...).

4. Actual behavior

AA0136 is reported only on the statement following Error(...). The statement following SalesLine.FieldError(Type) produces no diagnostic.

Additional analysis: the rule's unreachable-after-throw detection matches an expression statement whose target method is named error and whose containing symbol is a built-in language class symbol. That second condition already holds for FieldError ΓÇö its containers (the Table and FieldRef language classes) are built-in class symbols, exactly like Dialog for Error. Only the literal name comparison excludes it, so extending the check to also accept FieldError (all four overloads: Record.FieldError(Field[, Text]), Record.FieldError(Field, ErrorInfo), FieldRef.FieldError([Text]), FieldRef.FieldError(ErrorInfo)) would be consistent with the existing design. TestField should not be added, as it only errors conditionally.

Found while investigating the inverse gap in a third-party analyzer: ALCops/Analyzers#463.

5. Versions:

  • AL Language: 18.0.2668733
  • Visual Studio Code: 1.134.0 (commit 110a328ea54b42367b803ec53ee0bf52ef26b419)
  • Business Central: N/A (compile-time CodeCop diagnostic; no server involved)
  • List of Visual Studio Code extensions that you have installed: AL Language extension only (all other extensions disabled while reproducing)
  • Operating System:
    • Windows
    • Linux
    • MacOS
Final Checklist

Please remember to do the following:

  • Search the issue repository to ensure you are reporting a new issue

  • Reproduce the issue after disabling all extensions except the AL Language extension

  • Simplify your code around the issue to better isolate the problem


Generated with Claude Fable 5

Internal work item: AB#647929

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 with the AA0136 unreachable-after-throw detection described in the issue, focusing on its method-name comparison and built-in language-class check. Reproduce the supplied AL code and verify that FieldError is treated like Error while conditional TestField remains excluded; done means both unconditional FieldError cases produce diagnostics.

Written by the indexing model from the issue text.

Assessment

Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.