What if we have a loop in which some actions occur that can cause an error. What if we need to continue iterating through the loop after the errors and save the errors to the log? Today I will show you how this can be done even for transactional operations.
There is a special built-in mechanism for catching errors called TryFunction. The mechanism for working with it is already well {target="_blank"}described in the documentation, but there is an important exception where TryFunction simply does not work. Database write transactions in try methods just don't work.
This means that these functions cannot be used for try methods:
But there is still an easy way to get around this limitation and handle errors even with write transactions. To do this, we can use a separate codeunit with a process call on OnRun. For example, there is a function with a loop that calls a separate codeunit:
local procedure SimulateErrors()
var
RunProcess: Codeunit "EL Run Process";
HasError: Boolean;
i: Integer;
begin
for i := 1 to 30 do begin
ClearLastError();
RunProcess.SetParams(GetOneOrTwo());
HasError := not RunProcess.Run();
if HasError then
InsertErrorLog();
Commit();
end;
end;
The codeunit itself has a simple structure:
codeunit 70300 "EL Run Process"
{
trigger OnRun()
begin
InsertRecord();
end;
procedure SetParams(RandomInt: Integer)
begin
gRandomInt := RandomInt;
end;
local procedure InsertRecord()
var
SimulateTransaction: Record "EL Simulate Transaction";
begin
SimulateTransaction.Init();
case gRandomInt of
1:
SimulateTransaction."Is Insert" := false;
2:
SimulateTransaction."Is Insert" := true;
end;
SimulateTransaction.Insert(true);
end;
var
gRandomInt: Integer;
}
A possible error in the process is processed with a probability of 50%, depending on the "Is Insert" field:
trigger OnInsert()
begin
Rec.TestField("Is Insert");
end;
As a result, we get a complete log of errors in write transactional processes:
Source code is available on github:
https://github.com/Drakonian/handle-and-collect-errors