bcquality/custom/knowledge/integration/make-failed-integration-messages-manually-resolvable.bad.al
Tharanga Chandrasekara 07140e2223 Add new action skills for AL testing and documentation
- Introduced `al-test-writer` to generate AL test codeunits for production objects based on TDD principles.
- Added `al-userguide-test-writer` to create test codeunits from user guide steps, mapping actions and assertions.
- Implemented `bc-extension-test-guide` to generate a comprehensive TEST_GUIDE.md for Business Central extensions, covering various categories.
- Created `bc-webclient-runner` to automate UI testing of the Business Central web client, capturing screenshots and asserting UI states.
- Developed `page-scripting-e2e` to produce a recording plan for Page Scripting, ensuring a structured approach to browser-level testing.
2026-06-07 12:26:47 +12:00

36 lines
1.8 KiB
AL

// Anti-pattern: failed messages are PURGED, and the only "retry" mints a NEW message. The
// payload and error context needed to diagnose the failure are destroyed, and the new id breaks
// idempotency so the receiver double-applies the side effect.
codeunit 50221 "Failed Cleanup Bad"
{
procedure PurgeFailed()
var
IntegrationMessage: Record "Integration Message";
begin
// BAD: deleting failed rows means a fix needs a code change and a redeploy, because there
// is no editable row for ops to correct and re-run. Every data-level failure becomes an
// engineering incident. Worse, the payload and the error that explain WHAT failed are gone,
// so diagnosis after the fact is impossible.
IntegrationMessage.SetRange(Status, IntegrationMessage.Status::Failed);
IntegrationMessage.DeleteAll(true);
end;
procedure RetryFailed(SourceRef: Text[100]; MsgType: Code[40]; Payload: Text)
var
NewMessage: Record "Integration Message";
begin
// BAD: a manual retry that creates a BRAND-NEW message with a fresh Message ID. The
// idempotency key is derived from the Message ID, so a new id means a new key, and the
// receiver sees this as a new request rather than a repeat of the failed one. If the
// original attempt had partly landed (a charge captured, a shipment booked), this retry
// applies the side effect a SECOND time. The correct fix is to re-run the EXISTING message.
NewMessage.Init();
NewMessage."Message ID" := CreateGuid();
NewMessage."External Reference" := SourceRef;
NewMessage.Type := MsgType;
NewMessage.Status := NewMessage.Status::New;
NewMessage.SetRequest(Payload);
NewMessage.Insert(true);
end;
}