Coletar erros
O código AL pode capturar vários erros e exibi-los na interface do usuário. Referenciado como erros coletáveis, esse recurso pode simplificar os cenários de validação. Especificamente, ele pode simplificar cenários em que é apresentada aos usuários uma lista de erros a serem corrigidos.
Normalmente, quando ocorrer um erro em um procedimento, o procedimento será interrompido no primeiro erro que encontrar. Essencialmente, o uso de erros coletáveis adiará o tratamento de erros até o fim da chamada do procedimento. A implementação do código AL não será interrompida em caso de erros. Em vez disso, continua até o fim e coleta os erros à medida que ocorrem.
O AL inclui vários métodos, propriedades e atributos projetados especificamente para o recurso de erros coletáveis.
ErrorInfo.Create(String [, Boolean] [, var Record] [, Integer] [, Integer] [, String] [, Verbosity] [, DataClassification] [, Dictionary of [Text, Text]]): cria um novo objeto ErrorInfo.
ErrorInfo.Callstack(): especifica uma pilha de chamadas na qual o objeto ErrorInfo foi coletado.
ErrorInfo.Collectible([Boolean]): especifica se o erro é coletável por meio de ErrorBehavior.Collect.
ErrorInfo.CustomDimensions([Dictionary of [Text, Text]]): um conjunto de dimensões, especificado como um dicionário relacionado ao erro.
ErrorInfo.FieldNo([Integer]): especifica a ID de campo à qual o erro se refere.
ErrorInfo.PageNo([Integer]): especifica o número de página ao qual o erro se refere.
ErrorInfo.RecordId([RecordId]): especifica a ID de registro à qual o erro se refere.
ErrorInfo.SystemId([Guid]): especifica a ID do sistema à qual o erro se refere.
ErrorInfo.TableId([Integer]): especifica a ID de tabela à qual o erro se refere.
ErrorInfo.AddAction(Text, Integer, Text): especifica uma ação para o erro.
O método AddAction aceita três parâmetros:
Caption: a cadeia de caracteres de texto que é exibida como a legenda da ação na interface do usuário do erro.
CodeunitID: a ID do Codeunit a ser executado quando a ação for iniciada por meio da interface do usuário de erro. A codeunit deve conter pelo menos um método global a ser chamado pela ação de erro. O método global deve ter um parâmetro de tipo de dados ErrorInfo para aceitar o objeto ErrorInfo.
Nome do Método: o nome do método no Codeunit, que é especificado pelo parâmetro CodeunitID, que você deseja executar para a ação.
Os métodos a seguir estão disponíveis no Tipo de dados do sistema para tratar erros coletados. Você pode invocar esses métodos usando a sintaxe de acesso a propriedades.
System.HasCollectedErrors(): obtém um valor que indica se foram coletados erros no escopo atual da coleção de erros.
System.GetCollectedErrors([Boolean]): obtém todos os erros coletados no escopo da coleção atual.
System.ClearCollectedErrors(): limpa todos os erros coletados do escopo da coleção atual.
Se você limpar a lista de erros coletados, as alterações feitas no banco de dados não serão revertidas. Portanto, na maioria dos casos, faz sentido combinar a operação de limpeza com uma instrução if Codeunit.Run then .....
O atributo ErrorBehavior especifica o comportamento de erros coletáveis no escopo do método. Adicionar [ErrorBehavior(ErrorBehavior.Collect)] a um procedimento possibilita coletar e manipular erros que são gerados no escopo do procedimento.
O exemplo de código a seguir ilustra como usar erros coletáveis. Ele é criado em torno da codeunit DoPost, que define critérios básicos sobre o que pode ou não ser incluído em campos da tabela. Esse procedimento será interrompido quando ocorrerem erros.
Os procedimentos PostWithErrorCollect () e PostWithErrorCollectCustomUI () mostram maneiras de coletar e apresentar esses erros, aplicando o atributo 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;
}