Promote events knowledge from community to Microsoft layer

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Jesper Schulz-Wedde 2026-06-25 14:04:14 +02:00
parent 3769d2fbf4
commit e2b7d534f9
3 changed files with 0 additions and 0 deletions

View file

@ -1,38 +0,0 @@
// Demonstration only. Shows the wrong pattern: raising the integration event inside a TryFunction body.
codeunit 50116 "Payment Processor Bad"
{
[IntegrationEvent(false, false)]
procedure OnBeforeSubmitPayment(var PaymentAmount: Decimal; var Cancel: Boolean)
begin
end;
procedure SubmitPayment(PaymentAmount: Decimal)
var
Success: Boolean;
begin
// TryFunction wraps both the event raise and the gateway call.
Success := TrySubmitPaymentInternal(PaymentAmount);
if not Success then
Error('Payment gateway call failed. Check connectivity and retry.');
end;
[TryFunction]
local procedure TrySubmitPaymentInternal(PaymentAmount: Decimal)
var
Cancel: Boolean;
Client: HttpClient;
Response: HttpResponseMessage;
begin
Cancel := false;
// BAD: event raised inside TryFunction. Any Error() thrown by a subscriber is caught here
// and silently swallowed - the subscriber's error never reaches the caller.
// A subscriber setting Cancel := true is also lost when TryFunction returns false.
OnBeforeSubmitPayment(PaymentAmount, Cancel);
if Cancel then
exit;
Client.Get('https://payments.example.com/submit?amount=' + Format(PaymentAmount), Response);
if not Response.IsSuccessStatusCode() then
Error('HTTP %1', Response.HttpStatusCode());
end;
}

View file

@ -1,38 +0,0 @@
// Demonstration only. Shows the correct pattern: raise the integration event before entering TryFunction.
codeunit 50114 "Payment Processor"
{
[IntegrationEvent(false, false)]
procedure OnBeforeSubmitPayment(var PaymentAmount: Decimal; var Cancel: Boolean)
begin
end;
procedure SubmitPayment(PaymentAmount: Decimal)
var
Cancel: Boolean;
Success: Boolean;
begin
Cancel := false;
// Event raised outside the try scope - subscriber errors propagate normally to the caller.
OnBeforeSubmitPayment(PaymentAmount, Cancel);
if Cancel then
exit;
// Only the operation that can fail transiently lives inside TryFunction.
Success := TryCallPaymentGateway(PaymentAmount);
if not Success then
Error('Payment gateway call failed. Check connectivity and retry.');
end;
[TryFunction]
local procedure TryCallPaymentGateway(PaymentAmount: Decimal)
var
Client: HttpClient;
Response: HttpResponseMessage;
begin
// ... build request, set headers ...
Client.Get('https://payments.example.com/submit?amount=' + Format(PaymentAmount), Response);
if not Response.IsSuccessStatusCode() then
Error('HTTP %1', Response.HttpStatusCode());
end;
}

View file

@ -1,26 +0,0 @@
---
bc-version: [all]
domain: events
keywords: [tryfunction, integration-event, subscriber, error-handling, silent-failure, event-publisher]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Do not raise integration events inside a TryFunction
## Description
A `TryFunction` catches all errors — including errors thrown by event subscribers. When an `[IntegrationEvent]` is raised inside a `TryFunction` body, any error a subscriber raises is silently swallowed by the TryFunction's error boundary. The subscriber's logic fails, the caller sees no error, and the calling code continues as if nothing happened. Subscribers have no way to signal failure to the caller.
## Best Practice
Raise the integration event before entering the TryFunction scope. The event and its subscribers execute outside the error boundary, so subscriber errors propagate normally to the caller. Move only the operation that genuinely needs error isolation (such as an HTTP call or a posting step) inside the TryFunction.
See sample: `avoid-raising-events-inside-try-functions.good.al`.
## Anti Pattern
Raising an integration event inside a TryFunction body. Subscriber failures are caught and discarded by the TryFunction. The subscriber contract — that a subscriber can signal failure to the caller — is silently broken.
See sample: `avoid-raising-events-inside-try-functions.bad.al`.