Actionable errors

This article describes how to handle error dialogs in AL code, specifically how to use the error handling framework to provide recommended actions to users to resolve errors more effectively.

For advice on how to design error dialogs that users understand, see User experience guidelines for errors.

Unblocking users with actionable errors

With Business Central 2023 release wave 2, the error handling framework has been enhanced to include promoted actions in both error dialogs and validation errors. These promoted actions are designed to assist users in resolving errors more effectively. There are currently two main scenarios to keep in mind when deciding how to use recommended actions:

  • Fix-it actions are recommended for scenarios where the system knows the correct value that should be used to resolve the error.
  • Show-it actions are recommended for scenarios when the system can identify the location where the error may be fixed by the user.

Here are some quick guidelines on when to use each type of error message and its accompanying recommended actions. However, it's essential to begin by considering whether the error could have been avoided in the first place.

Error type Description
Task dialogs Task dialogs are used when an error can be mitigated by the user choosing between two (sometimes three) different options to continue their task without encountering an error.
Error messages with Fix-it actions Fix-it actions can be used when the cause and solution to the error is known and can be solved by users with just one step.
Error messages with Show-it actions Show-it actions can be used when an error must be corrected on a related table. A Show-it action can then offer a shortcut to the related table, enabling users to correct the error by themselves with one or multiple steps, while keeping the context of their current task.

Error messages with Fix-it actions

Fix-it actions are for when the correct value is known. If all the following four statements are true for your error case, then consider adding a recommended Fix-it action in your error message to enable users to easily unblock themselves from the error.

  1. Is the solution to the error known?
  2. Is the error location on the current page?
  3. Can the error (value) be corrected with one action?
  4. Does the user have permission to make the required correction?

Guidance for button labels for Fix-it actions

To achieve consistency in the user experience of Fix-it actions, consider following these guidelines for button labels:

  • Fix-it actions are often phrased: “Set value to...”.
    • Such as: “Set value to 10”, “Set Status to Open”, or “Set value to HOME”.
  • Fix-it action tooltips are often phrased: “Sets the value...”.
  • Value states are capitalized such as: Yes, Open, Released. Avoid signs for values such as = ,“”, ().

Example (error dialog with a Fix-it action)

The following AL code illustrates how to set up an error dialog with a Fix-it action.

var 
    dimension: Text[30];
    vendorCode: Text[30];
    FixitErrorInfo: ErrorInfo;
begin
    // setup the error info object
    FixitErrorInfo.Title('The line dimension value isn''t valid');
    FixitErrorInfo.Message(
        StrSubstNo('The dimension value must be blank for the dimension %1 for Vendor %2', dimension, vendorCode)
    );
    FixitErrorInfo.DetailedMessage('Add some text to help the person troubleshooting this error.');

    FixitErrorInfo.AddAction(
        'Set value to blank', 
        Codeunit::FixitCodeunit, 
        FixitCodeunitMethodName
    );
    
    Error(FixitErrorInfo);
end

If the user experience the error they see the following error dialog

Error dialog with fix-it action

Example (validation error with a Fix-it action)

The following AL code illustrates how to set up field validation with a Fix-it action.

... 
field(17; "Qty. to Invoice"; Decimal)
{
    // maybe some field properties

    trigger OnValidate()
    var
        CannotInvoiceErrorInfo: ErrorInfo;
        CheckField: Boolean;
    begin
        // some calculations here

        CheckField := // calculate if true or false

        if (CheckField)
        then begin
            // setup the error info object
            CannotInvoiceErrorInfo.Title := 'Qty. to Invoice isn''t valid';
            CannotInvoiceErrorInfo.Message := 
                StrSubstNo('You cannot invoice more than %1 units.', MaxQtyToInvoice());
            CannotInvoiceErrorInfo.DetailedMessage('Add some text to help the person troubleshooting this error.');

            CannotInvoiceErrorInfo.RecordId := Rec.RecordId;
            CannotInvoiceErrorInfo.AddAction(
                StrSubstNo('Set value to %1', MaxQtyToInvoice()), 
                Codeunit::FixitCodeunit, 
                FixitCodeunitMethodName
            );

            Error(CannotInvoiceErrorInfo);
        end;
        // maybe more validation logic here
    end;
}
...

If the user experience that the field can't be validated, they see the following dialog

Validation error with fix-it action

Error messages with Show-it actions

Show-it actions are for when the error location is known. A shortcut can then be provided to show the related page to enable users to easily unblock themselves from the error. If all the following four statements are true for your error case, then consider adding a recommended Show-it action in your error message.

  1. Is the solution to the error known?
  2. Is the error correction location known and is it on a related table?
  3. Can you show the related table with one action?
  4. Does the user have permission to make the required correction?

Guidance for button labels for Show-it actions

To achieve consistency in the user experience of Show-it actions, consider following these guidelines for button labels:

  • Show-it actions are phrased: “Show...”.
    • Such as: “Show User Setup”, “Show Items list” or “Show Item 70062”.
  • Show-it action tooltips are often phrased: “Opens page:..”.
    • Note: Avoid using “Open” for the button label, as it can be confused with opening the status of the document. Instead use “Show” and use the tooltip to write out “Opens Page:...”.
  • Captions are capitalized, such as: Item, Direct Posting and G/L Account.

Example (error dialog with a Show-it action)

The following AL code illustrates how to set up an error dialog with a Show-it action.

procedure ShowShipmentDialog()
var
    ErrorNoLinesToCreate: ErrorInfo;
    SomeCheckCondition: Boolean;
begin
    // some business logic 

    SomeCheckCondition := // calculate if true or false        

    if (SomeCheckCondition)
    begin
        // maybe some business logic here 

        // setup the error info object
        ErrorNoLinesToCreate.Title := 'There are no new warehouse shipment lines to create';
        ErrorNoLinesToCreate.Message := 'This usually happens when warehouse shipment lines [...]'; 
        ErrorNoLinesToCreate.DetailedMessage('Add some text to help the person troubleshooting this error.');

        ErrorNoLinesToCreate.PageNo := Page::"Warehouse Shipment List";
        ErrorNoLinesToCreate.AddNavigationAction('Show open lines');,

        Error(ErrorNoLinesToCreate);

        // maybe more business logic here 
    end;

    // some more business logic here

If the user experience the error they see the following error dialog

Error dialog with show-it action

Example (validation error with one Show-it action)

The following AL code illustrates how to set up a validation error dialog with a Show-it action.

... 
field(59; "Gen. Prod. Posting Group"; Code[20])
{
    // maybe some field properties

    trigger OnValidate()
    var
        CheckIfFieldIsEmpty: Boolean;
        FieldEmptyErrorInfo: ErrorInfo;
    begin
        CheckIfFieldIsEmpty := // calculate if true or false        

        if (CheckIfFieldIsEmpty)
        then begin
            // setup the error info object
            FieldEmptyErrorInfo.Message := 
                StrSubstNo('Gen. Prod. Posting Group must have a value in item: %1. It can''t be zero or empty.', ItemNo);
            FieldEmptyErrorInfo.DetailedMessage('Add some text to help the person troubleshooting this error.');

            CannotInvoiceErrorInfo.RecordId := ItemRec.RecordId;
            CannotInvoiceErrorInfo.AddNavigationAction(
                StrSubstNo('Show Item %1', ItemNo)
            );
            ChangeNotAllowedErrorInfo.PageNo(Page::"Item Card");

            Error(CannotInvoiceErrorInfo);
        end;

        // maybe more validation logic here
    end;
}
...

If the user experience that the field can't be validated, they see the following dialog

Validation error with show-it action

Error messages with multiple actions - how to use them?

Error messages can have up to two recommended actions. In this section, we show some different examples of how to use multiple actions and why.

Example (error dialog with two actions)

The following AL code illustrates how to set up an error dialog with two actions.

var
    ErrorDialogWithTwoActions: ErrorInfo;
    DimensionCode: Code[20];
    VendorCode: Code[20];
begin
    // set values for DimensionCode, VendorCode variables

    // setup the error info object
    ErrorDialogWithTwoActions.Title := 'The line dimension value isn''t valid';
    ErrorDialogWithTwoActions.Message := StrSubstNo('The dimension value must be blank for the dimension %1 for Vendor %2', DimensionCode, VendorCode); 
    ErrorDialogWithTwoActions.DetailedMessage('Add some text to help the person troubleshooting this error.');

    ErrorDialogWithTwoActions.AddAction(
        'Set value to blank',
        Codeunit::FirstFixitCodeunit, 
        "FirstFixitCodeunitMethodName"
    );
    ErrorDialogWithTwoActions.AddAction(
        'OK',
        Codeunit::SecondFixitCodeunit, 
        "SecondFixitCodeunitMethodName"
    );

    Error(ErrorDialogWithTwoActions);
end;

In this error dialog case, the recommended Fix-it action sets the value to blank, meaning that it clears out the field value.

Notice the error dialog has two actions. In error cases both buttons are styled equally as secondary buttons, to allow users to consider the most suitable way to get unblocked for their case.

If the user experience the error they see the following error dialog

Error dialog with multiple actions

Example (validation error with two promoted actions)

The following AL code illustrates how to set up field validation with two actions.

field(4; "Account No."; Code[20])
{
    // maybe some field properties

    trigger OnValidate()
    var
        PendingApprovalErrorInfo: ErrorInfo;
    begin
        SomeCheckCondition := // calculate if true or false        

        if (SomeCheckCondition)
        then begin        
            PendingApprovalErrorInfo.Message := 'You can''t modify a record pending approval. Add a comment or reject the approval to modify the record.';
            PendingApprovalErrorInfo.DetailedMessage('Add some text to help the person troubleshooting this error.');
            
            PendingApprovalErrorInfo.PageNo := Page::"Comments";
            PendingApprovalErrorInfo.AddNavigationAction('Show comments');

            PendingApprovalErrorInfo.AddAction(
                'Reject approval'
                Codeunit::SecondFixitCodeunit, 
                SecondFixitCodeunitMethodName
            );

            Error(PendingApprovalErrorInfo);
        end;
    end;
}

Here the Show-it action shows the related Comments table, and the Fix-it action rejects the approval.

Users can also get unblocked by refreshing the page or copying the error details for sharing and troubleshooting.

If the user experience that the field can't be validated, they see the following dialog

Validation error with multiple  actions

Error messages with no actions (final resort)

When there isn’t any known solution to recommend, the error dialog has one primary OK button. Users can copy and share the full error details needed for troubleshooting and support.

The following AL code illustrates how to set up an error dialog with no actions (which is also the standard behavior of the Error method)

var
    ErrorDialogNoActions: ErrorInfo;
begin
    // setup the error info object
    ErrorDialogNoActions.Title := 'The ''Starting Date'' isn''t valid';
    ErrorDialogNoActions.Message := 'The ''Starting Date'' must be the first date of an accounting period. Try changing the date to first date of the month.'; 
    ErrorDialogNoActions.DetailedMessage('Add some text to help the person troubleshooting this error.');

    Error(ErrorDialogNoActions);
end;

If the user experience the error they see the following error dialog

Error dialog with no solution

See Also

Failure modeling and robust coding practices
User experience guidelines for errors
Understanding the error dialog
Dialog.Error(ErrorInfo) Method
AL error handling