收集错误
AL 代码可捕获多个错误并在用户界面中显示。 此功能称为可收集错误,可简化验证应用场景。 具体来说,它可简化用户需要修复错误列表的应用场景。
通常,如果过程中发生错误,此过程会在遇到第一个错误时停止。 如果使用可收集的错误,基本上可将错误处理推迟到过程调用结束后进行。 遇到错误时,AL 代码实现不会停止。 相反,它将一直持续到最后,并在出现错误时收集错误。
AL 包含专为可收集错误功能设计的多种方法、属性和特性。
ErrorInfo.Create(String [, Boolean] [, var Record] [, Integer] [, Integer] [, String] [, Verbosity] [, DataClassification] [, Dictionary of [Text, Text]]) - 创建新 ErrorInfo 对象。
ErrorInfo.Callstack() - 指定收集 ErrorInfo 对象的调用堆栈。
ErrorInfo.Collectible([Boolean]) - 指定错误是否可通过 ErrorBehavior.Collect 收集。
ErrorInfo.CustomDimensions([Dictionary of [Text, Text]]) - 一组指定为错误相关字典的维度。
ErrorInfo.FieldNo([Integer]) - 指定错误相关的字段 ID。
ErrorInfo.PageNo([Integer]) - 指定错误相关的页码。
ErrorInfo.RecordId([RecordId]) - 指定错误相关记录的记录 ID。
ErrorInfo.SystemId([Guid]) - 指定错误相关记录的系统 ID。
ErrorInfo.TableId([Integer]) - 指定错误相关的表 ID。
ErrorInfo.AddAction(Text, Integer, Text) - 为错误指定操作。
AddAction 方法接受三个参数:
Caption:在错误 UI 中作为操作标题显示的文本字符串。
CodeunitID:从错误 UI 启动操作时要运行的 Codeunit 的 ID。 Codeunit 应至少包含一个全局方法,才能被错误操作调用。 全局方法必须有一个 ErrorInfo 数据类型参数,用于接受 ErrorInfo 对象。
Method Name:Codeunit 中方法的名称,由您要为操作运行的 CodeunitID 参数指定。
系统数据类型中的以下方法可用于处理收集的错误。 您可使用属性访问语法调用这些方法。
System.HasCollectedErrors() - 获取指示是否已在当前错误收集范围内收集错误的值。
System.GetCollectedErrors([Boolean]) - 获取当前收集范围内所有收集的错误。
System.ClearCollectedErrors() - 清除当前收集范围内所有收集的错误。
如清除收集的错误列表,则数据库中进行的更改将不会回滚。 因此,大多数情况下,将清除操作与 if Codeunit.Run then ... 语句结合会有所帮助。
ErrorBehavior 特性 指定方法范围内可收集错误的行为。 在过程中添加 [ErrorBehavior(ErrorBehavior.Collect)] 可收集和处理过程范围内引发的错误。
以下代码示例说明了如何使用可收集错误。 它围绕 DoPost codeunit 构建,此代码单位设置有关表字段中可包含或不可包含哪些内容的基本条件。 此过程在发生错误时会停止。
PostWithErrorCollect () 和 PostWithErrorCollectCustomUI () 过程展示通过应用 ErrorBehavior(ErrorBehavior::Collect) 特性收集和呈现这些错误的方式。
pageextension 50100 CollectingErrorsExt extends "Customer List"
{
actions
{
addfirst(processing)
{
// This action doesn't collect errors. Any procedure will stop on the first error that occurs,
// and return the error.
action(Post)
{
ApplicationArea = All;
trigger OnAction()
var
i: Record Integer;
begin
i.Number := -9;
Codeunit.Run(Codeunit::DoPost, i);
end;
}
// This action collects errors. The PostWithErrorCollect procedure continues on errors,
// and displays the errors in a dialog to the user done.
action(PostWithErrorCollect)
{
ApplicationArea = All;
trigger OnAction()
begin
PostWithErrorCollect();
end;
}
// This action collects errors. The PostWithErrorCollectCustomUI procedure continues on errors,
// and displays error details in a list page when done.
// This implementation illustrates how you could design your own UI for displaying and
// troubleshooting errors.
action(PostWithErrorCollectCustomUI)
{
ApplicationArea = All;
trigger OnAction()
begin
PostWithErrorCollectCustomUI();
end;
}
}
}
[ErrorBehavior(ErrorBehavior::Collect)]
procedure PostWithErrorCollect()
var
i: Record Integer;
begin
i.Number := -9;
Codeunit.Run(Codeunit::DoPost, i);
// After executing the codeunit, there will be collected errors,
// and therefore an error dialog will be shown when exiting this procedure.
end;
[ErrorBehavior(ErrorBehavior::Collect)]
procedure PostWithErrorCollectCustomUI()
var
errors: Record "Error Message" temporary;
error: ErrorInfo;
i: Record Integer;
begin
i.Number := -9;
// By using Codeunit.Run, you ensure any changes to the database within
// Codeunit::DoPost are rolled back in case of errors.
if not Codeunit.Run(Codeunit::DoPost, i) then begin
// If Codeunit.Run fails, a non-collectible error was encountered,
// add this to the list of errors.
errors.ID := errors.ID + 1;
errors.Description := GetLastErrorText();
errors.Insert();
end;
// If there are collected errors, iterate through each of them and
// add them to "Error Message" record.
if HasCollectedErrors then
foreach error in system.GetCollectedErrors() do begin
errors.ID := errors.ID + 1;
errors.Description := error.Message;
errors.Validate("Record ID", error.RecordId);
errors.Insert();
end;
// Clearing the collected errors will ensure the built-in error dialog
// will not show, but instead show our own custom "Error Messages" page.
ClearCollectedErrors();
page.RunModal(page::"Error Messages", errors);
end;
}
codeunit 50100 DoPost
{
TableNo = Integer;
trigger OnRun()
begin
if Number mod 2 <> 0 then
Error(ErrorInfo.Create('Number should be equal', true, Rec, Rec.FieldNo(Number)));
if Number <= 0 then
Error(ErrorInfo.Create('Number should be larger than 0', true, Rec, Rec.FieldNo(Number)));
if Number mod 3 = 0 then
Error(ErrorInfo.Create('Number should not be divisible by 10', true, Rec, Rec.FieldNo(Number)));
// Everything was valid, do the actual posting.
end;
}