* knowledge: improve review precision from BCApps PR 10080 feedback * Update microsoft/knowledge/appsource/object-affixes-prevent-collisions.md Co-authored-by: Natalie Karolak, MVP <34504100+NKarolak@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Jesper Schulz-Wedde <JesperSchulz@users.noreply.github.com> Co-authored-by: Natalie Karolak, MVP <34504100+NKarolak@users.noreply.github.com>
2.7 KiB
| bc-version | domain | keywords | technologies | countries | application-area | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
error-handling |
|
|
|
|
Choose TestField For Conditional Checks And FieldError For Already-Failed Validation
Description
TestField and FieldError look interchangeable but behave differently, and choosing the wrong one produces either dead code or a check that never fires. TestField performs the comparison itself and throws only when the field is empty or does not match the supplied value; FieldError performs no comparison and always raises an error the moment it is reached. Both attach the field caption and the record's primary-key context to the message automatically, which is why neither should be replaced by a hand-built Error call that interpolates the field name as a literal.
Best Practice
Use TestField when the condition is a simple presence-or-equality check on a single field — mandatory-field gates and prerequisite checks at the top of a procedure read clearly and self-document intent. Use FieldError inside an OnValidate trigger or a validation procedure where surrounding business logic has already determined the value is invalid and you want a specific, custom message. Rely on the built-in field-and-record context both methods add rather than re-stating the field name in the text.
A page action's OnAction trigger is a different case: a page action is only invocable through its own UI control, so when the action's Enabled property is already bound to the same condition the trigger would otherwise TestField, the control cannot be clicked while the field is blank and the field can never reach the trigger empty. Adding a TestField there is redundant defensive code, not a missing check — flag it only when the trigger can run through a path Enabled does not cover (a shared procedure, an API, or a condition broader than what gates the action).
See sample: fielderror-vs-testfield.good.al.
Anti Pattern
Calling FieldError to "test" a field — placing it on a path that is reached unconditionally and expecting it to validate — terminates execution every time because FieldError never evaluates a condition. The inverse smell is reaching for TestField when the rule needs a tailored message, then bolting a vague generic string onto a check that cannot express the real business reason. A reviewer can spot the first by a FieldError that is not guarded by a preceding if, and the second by a TestField whose intent comment describes a condition more complex than presence or equality.
See sample: fielderror-vs-testfield.bad.al.