收集错误

已完成

AL 代码可捕获多个错误并在用户界面中显示。 此功能称为可收集错误,可简化验证应用场景。 具体来说,它可简化用户需要修复错误列表的应用场景。

通常,如果过程中发生错误,此过程会在遇到第一个错误时停止。 如果使用可收集的错误,基本上可将错误处理推迟到过程调用结束后进行。 遇到错误时,AL 代码实现不会停止。 相反,它将一直持续到最后,并在出现错误时收集错误。

AL 包含专为可收集错误功能设计的多种方法、属性和特性。

AddAction 方法接受三个参数:

  • Caption:在错误 UI 中作为操作标题显示的文本字符串。

  • CodeunitID:从错误 UI 启动操作时要运行的 Codeunit 的 ID。 Codeunit 应至少包含一个全局方法,才能被错误操作调用。 全局方法必须有一个 ErrorInfo 数据类型参数,用于接受 ErrorInfo 对象。

  • Method Name:Codeunit 中方法的名称,由您要为操作运行的 CodeunitID 参数指定。

系统数据类型中的以下方法可用于处理收集的错误。 您可使用属性访问语法调用这些方法。

如清除收集的错误列表,则数据库中进行的更改将不会回滚。 因此,大多数情况下,将清除操作与 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;
}