diff --git a/custom/knowledge/error-handling/ambiguous-record-failure-handling-must-be-clarified.md b/custom/knowledge/error-handling/ambiguous-record-failure-handling-must-be-clarified.md new file mode 100644 index 0000000..feca81f --- /dev/null +++ b/custom/knowledge/error-handling/ambiguous-record-failure-handling-must-be-clarified.md @@ -0,0 +1,54 @@ +--- +bc-version: [all] +domain: error-handling +keywords: [insert, modify, delete, get, rename, boolean-return, clarify-before-building, ambiguous] +technologies: [al] +countries: [w1] +application-area: [all] +--- + +# Ambiguous record-failure handling must be clarified, not guessed + +## Description + +`Insert`, `Modify`, `Delete`, `Get`, and `Rename` all return a Boolean +indicating success. There are two legitimate ways to use that: let AL +raise its own runtime error when the return value is ignored and the call +fails, or check the return value explicitly and decide what happens on +failure (`if not Rec.Insert() then ...`). Both are correct in the right +context — an ignored `Get()` failing is often exactly the right behavior +when the record is expected to exist and its absence is a genuine bug; +an ignored `Insert()` failing on a duplicate key might instead be a normal, +recoverable case the caller should handle gracefully. + +Because both are legitimate, this is not a pattern an AI assistant should +resolve by guessing. When it is unclear from the surrounding code, the +task description, or the object's existing conventions whether a given +failure should surface as AL's implicit runtime error or be handled +explicitly, ask the developer which behavior is intended before writing +the call — the same way [[clarify-before-building]] applies to any other +underspecified requirement. Silently picking one approach risks either +swallowing a failure the developer needed to see, or crashing a flow the +developer expected to degrade gracefully. + +## Best Practice + +```al +// Failure is expected and recoverable — handle it explicitly. +if not Customer.Insert() then + Error('Customer %1 already exists.', Customer."No."); + +// Failure would indicate a genuine bug — let it surface as AL's own error. +Customer.Get(CustomerNo); +``` + +When genuinely unsure which case applies, ask: "Should a failed +Insert/Modify/Delete/Get here be handled as an expected, recoverable +outcome, or is it a bug we want to surface immediately?" + +## Anti Pattern + +Silently choosing to ignore the return value (or silently choosing to wrap +every call in an `if not ... then` with a generic error message) without +first checking whether the surrounding code, task, or object convention +already signals which behavior is intended.