Study guide

13.3 Error Handling: ErrorInfo, TryFunctions & Collectible Errors

Microsoft Dynamics 365 Business Central Developer MB-820

Track your progress as you read

Finished sections get a check mark.

1 Chapter 1: Business Central Architecture & Platform Foundation

1.1 Business Central Architecture & Extensions Model 1.2 Customization Lifecycle: Cloud (SaaS) vs. On-Premises 1.3 Base Application, System Application & AppSource

2 Chapter 2: Development Environment & Configuration

2.1: Development Environment Setup: VS Code, AL: Go! Projects & Sandboxes 2.2: AL Configuration Files: app.json & launch.json Parameters 2.3: Multi-Root Workspaces & Project Dependencies

3 Chapter 3: Extension Lifecycle: Debugging, Deployment, Multilanguage & Maintenance

3.1 Debugging & Snapshot Debugging in Visual Studio Code 3.2 Extension Deployment & Schema Synchronization Modes 3.3 Multilanguage Development with XLIFF & Translation Files 3.4 Extension Maintenance, Deprecation & Breaking Changes

4 Chapter 4: Tables, Table Extensions & Data Modeling

4.1: Building Tables, Fields, Keys & Data Types 4.2: Table Extensions & Table Modifications 4.3: FlowFields, FlowFilters & Table Relations 4.4: Enums, Enum Extensions & Extensible Types

5 Chapter 5: Pages, Page Extensions & Role Centers

5.1: Page Types, Anatomy & Control Structure 5.2: Building Card, List & Document Pages 5.3: Page Extensions & Page Customizations 5.4: Role Centers, Headlines & Cue Data Modeling

6 Chapter 6: Reports & Document Generation

6.1 Report Architecture, DataItems & Dataset Design 6.2 Report Layouts: RDLC, Word, Excel & Multilanguage 6.3 Document Reports & Request Page Programming 6.4 Processing-Only Reports & Report Substitutions

7 Chapter 7: XMLports & Data Exchange

7.1 XMLport Architecture, Formats & Properties 7.2 XMLport Node Hierarchy, Triggers & Stream Manipulation

8 Chapter 8: Codeunits, Events, Triggers & Interfaces

8.1 Codeunit Types, Execution & SingleInstance Codeunits 8.2 Events, Publishers, Subscribers & Event Isolation 8.3 Interfaces, Polymorphism & Dynamic Codeunit Invocation 8.4 Installation & Upgrade Codeunits, Data Transfer & Archive

9 Chapter 9: Entitlements, Permissions & Queries

9.1 Permission Sets & Permission Set Extensions 9.2 Inherent Permissions, Inherent Entitlements & Security Scoping 9.3 Query Objects: Joins, Aggregation & Query as Report Data Source

10 Chapter 10: UI Customization, User Assistance & Onboarding

10.1 Profile Objects & Custom Page Views in AL 10.2 User Assistance: ToolTips, Teaching Tips & In-App Tours 10.3 Assisted Setup, Guided Experience & Onboarding Checklists

11 Chapter 11: Business Central Design Patterns & Data Process Model

11.1 Functional Table Types: Master Data, Supplemental & Setup Patterns 11.2 Document Standards: Header, Line, History & Journal Architectures 11.3 Data Process Model & Posting Routine Architecture

12 Chapter 12: AL Language Fundamentals, Data Types & Variables

12.1 AL Syntax, Variable Scope, Primitive & Complex Data Types 12.2 Expressions, Control Flow Statements & Built-in Functions 12.3 Access Modifiers (Public, Internal, Local) & Code Scoping

13 Chapter 13: Data Manipulation, Streams & Error Handling

13.1 Record Operations: Get, FindSet, ModifyAll & Filter Functions 13.2 Streams, File Management & TempBlob 13.3 Error Handling: ErrorInfo, TryFunctions & Collectible Errors

14 Chapter 14: Testing, Test Toolkit & Automation

14.1 Testing Architecture & the Test Toolkit 14.2 Authoring Test Codeunits & UI Handler Functions

15 Chapter 15: Telemetry, Performance Optimization & Analyzers

15.1 Telemetry Configuration & Azure Application Insights 15.2 Custom Telemetry Signals with Session.LogMessage & KQL 15.3 Performance Profiler, SetLoadFields & Query Optimization 15.4 AL Analyzers: CodeCop, AppSourceCop, UICop & PTECop

16 Chapter 16: REST Web Services & JSON in AL

16.1 HttpClient, HttpRequestMessage & REST API Consumption 16.2 JSON Processing: JsonObject, JsonArray, JsonValue & JsonToken

17 Chapter 17: API Pages, OData, Read Scale-Out & OAuth

17.1 API Pages (PageType=API), OData Web Services & REST Endpoints 17.2 Bound and Unbound OData Actions with [ServiceEnabled] 17.3 Read Scale-Out Architecture & DataAccessIntent Configuration 17.4 Microsoft Entra ID App Registrations & OAuth 2.0 Integration

13.3 Error Handling: ErrorInfo, TryFunctions & Collectible Errors

Key Takeaways Explain This Topic AI

Traditional error handling via Error(), FieldError(), and TestField() halts code execution immediately, presents a modal dialog, and rolls back all database modifications in the current transaction.

The modern ErrorInfo object allows developers to construct rich, structured errors containing custom titles, actionable FixIt buttons, navigation links, and telemetry metadata.

Collectible errors configured with [ErrorBehavior(ErrorBehavior::Collect)] allow procedures to gather multiple validation errors across a batch process and present them all together in a single consolidated dialog.

TryFunctions ([TryFunction]) catch runtime exceptions without displaying error dialogs to the user, returning false upon failure and capturing error details in GetLastErrorText().

Crucial TryFunction Restriction: Any procedure marked as a [TryFunction] (or any child procedure called within it) is strictly forbidden from performing database write operations (Insert, Modify, Delete, ModifyAll, DeleteAll) or calling Commit().

Last updated: August 2026

13.3 Error Handling: ErrorInfo, TryFunctions & Collectible Errors

Robust error handling is essential for mission-critical enterprise ERP systems. In Microsoft Dynamics 365 Business Central, unhandled errors immediately halt execution and roll back active database transactions to preserve data integrity. Modern AL provides advanced error-handling architectures, including structured ErrorInfo objects , actionable FixIt buttons , collectible error batching , and non-fatal [TryFunction] exception catching. For the MB-820 exam, developers must master traditional error statements, the modern ErrorInfo framework, and the strict transactional restrictions governing TryFunctions.

1. Traditional Error Handling & Assertions

AL includes three classic error-raising methods designed to validate business rules and abort invalid operations. local procedure ValidateCustomerRecord(var Customer: Record Customer)

  • begin
  • // 1. TestField Assertion: Verifies field is not blank or matches expected value
  • Customer.TestField("Gen. Bus. Posting Group"); // Throws error if blank
  • Customer.TestField("Credit Limit (LCY)", 10000); // Throws error if not equal to 10000
  • // 2. FieldError: Localized contextual field error
  • if Customer."Credit Limit (LCY)" < 0 then
  • Customer.FieldError("Credit Limit (LCY)", 'cannot be negative');
  • // 3. Standard Error: Custom formatted message
  • if Customer.Blocked = Customer.Blocked::All then
  • Error('Customer %1 is blocked for all transactions.', Customer."No.");
  • end;
  • Traditional Error Methods Comparison

TestField(Field [, ExpectedValue]) : Asserts that a field contains a non-blank (non-zero/non-empty) value. If an ExpectedValue is supplied, it verifies that the field equals that exact value. If the test fails, AL throws a standardized, localized runtime error (e.g., 'Gen. Bus. Posting Group must have a value in Customer: No.=10000' ).

FieldError(Field [, CustomText]) : Throws an error specifically tied to a field. Business Central automatically formats the error message to include the table name, primary key, field caption, and the invalid value.

Error(Message [, Param1...]) : Throws an unhandled exception with a custom message string, immediately halting execution and displaying a modal error dialog.

Transactional Impact: All traditional error methods ( Error , FieldError , TestField ) trigger an immediate transaction rollback . Any pending database inserts, modifications, or deletions executed during the current transaction are discarded.

2. Modern Error Framework: ErrorInfo & Actionable Errors

To modernize the user experience, AL introduced the ErrorInfo object . Instead of plain text modal dialogs, ErrorInfo enables rich, structured error cards equipped with diagnostic telemetry, navigation links, and direct remedial action buttons ("Fix It"). local procedure CheckPostingSetupWithFixAction(CustPostingGroupCode: Code[20])

  • var
  • CustPostingGroup: Record "Customer Posting Group";
  • MyErrorInfo: ErrorInfo;
  • begin
  • if not CustPostingGroup.Get(CustPostingGroupCode) then begin
  • MyErrorInfo.Title('Missing Customer Posting Group');
  • MyErrorInfo.Message(StrSubstNo('The Customer Posting Group "%1" does not exist.', CustPostingGroupCode));
  • MyErrorInfo.DetailedMessage('Configure the posting group before attempting to post sales documents.');
  • MyErrorInfo.ErrorType := ErrorType::Client;
  • MyErrorInfo.Verbosity := Verbosity::Error;
  • MyErrorInfo.DataClassification := DataClassification::CustomerContent;
  • // Add an Actionable FixIt button to the error dialog
  • MyErrorInfo.AddAction('Create Posting Group', Codeunit::"Posting Setup Fixes", 'CreateMissingGroup');
  • // Associate error with specific table and field for UI highlighting
  • MyErrorInfo.RecordId := CustPostingGroup.RecordId;
  • MyErrorInfo.FieldNo := CustPostingGroup.FieldNo(Code);
  • Error(MyErrorInfo);
  • end;
  • end;
  • ErrorInfo Key Properties & Methods

Title : Short summary header displayed prominently at the top of the modern error card.

Message : Primary user-facing error explanation.

DetailedMessage : Extended technical details for administrators and developers.

ErrorType : Categorizes the error ( ErrorType::Client for user validation, ErrorType::Internal for platform exceptions).

RecordId / FieldNo / TableId : Binds the error to a specific record and field, allowing the web client to highlight the invalid field on the user interface.

AddAction(Title, CodeunitId, MethodName) : Adds an actionable button to the error dialog that runs a specific procedure to rectify the issue automatically.

AddNavigationAction(Title) : Opens the relevant setup page or document card directly from the error window.

3. Collectible Errors: Batch Validation

In high-volume batch processing (such as posting 500 journal lines or importing 1,000 orders), throwing an immediate Error() on the first invalid row forces the user into a frustrating cycle of fixing one error at a time. Collectible Errors allow AL code to gather all validation failures and present them in a single comprehensive list. [ErrorBehavior(ErrorBehavior::Collect)]

  • procedure ValidateBatchSalesOrders(var SalesHeader: Record "Sales Header")
  • var
  • OrderErrorInfo: ErrorInfo;
  • begin
  • if SalesHeader.FindSet() then
  • repeat
  • if SalesHeader."Posting Date" = 0D then begin
  • OrderErrorInfo := ErrorInfo.Create(
  • StrSubstNo('Order %1 is missing a Posting Date.', SalesHeader."No."),
  • true // Collectible = true
  • );
  • OrderErrorInfo.RecordId := SalesHeader.RecordId;
  • OrderErrorInfo.FieldNo := SalesHeader.FieldNo("Posting Date");
  • Error(OrderErrorInfo); // Does NOT halt execution; registers error in collection
  • end;
  • if SalesHeader."Customer Posting Group" = '' then begin
  • OrderErrorInfo := ErrorInfo.Create(
  • StrSubstNo('Order %1 is missing Customer Posting Group.', SalesHeader."No."),
  • true
  • );
  • OrderErrorInfo.RecordId := SalesHeader.RecordId;
  • Error(OrderErrorInfo);
  • end;
  • until SalesHeader.Next() = 0;
  • end;
  • Mechanics of Collectible Errors

The executing procedure must be decorated with the attribute [ErrorBehavior(ErrorBehavior::Collect)] .

The ErrorInfo instance is initialized as collectible (e.g., ErrorInfo.Create('Message', true) or setting ErrorInfo.Collectible := true ).

When Error(MyErrorInfo) is invoked, the AL runtime does not abort execution . Instead, it adds the ErrorInfo to an internal collection and continues executing the remainder of the routine.

Developers can query collected errors programmatically using system.GetCollectedErrors() or allow the runtime to display the aggregated error review page upon procedure termination.

Loading diagram... AL Error Handling & TryFunction Transaction Lifecycle

4. TryFunctions: Mechanics & Strict Restrictions

TryFunctions allow developers to catch and handle runtime exceptions in AL without aborting code execution or displaying error dialogs to the user. local procedure SafeProcessExternalOrder(OrderPayload: Text): Boolean

  • var
  • ErrorMessage: Text;
  • begin
  • // Invoke TryFunction
  • if not TrySendOrderToApi(OrderPayload) then begin
  • ErrorMessage := GetLastErrorText();
  • // Log error to telemetry or integration log table
  • LogIntegrationError('OrderSync', ErrorMessage);
  • ClearLastError();
  • exit(false);
  • end;
  • exit(true);
  • end;
  • [TryFunction]
  • local procedure TrySendOrderToApi(Payload: Text)
  • var
  • HttpClient: HttpClient;
  • HttpResponse: HttpResponseMessage;
  • HttpContent: HttpContent;
  • begin
  • HttpContent.WriteFrom(Payload);
  • // If network fails or timeout occurs, TryFunction intercepts error
  • if not HttpClient.Post('https://api.logistics.com/orders', HttpContent, HttpResponse) then
  • Error('Failed to establish connection to logistics endpoint.');
  • if not HttpResponse.IsSuccessStatusCode() then
  • Error('Logistics API returned HTTP Status %1', HttpResponse.HttpStatusCode());
  • end;
  • Key TryFunction System Functions

GetLastErrorText() : Returns the error message string generated by the failed TryFunction.

GetLastErrorCallStack() : Returns the AL execution call stack leading to the error.

ClearLastError() : Clears the last recorded error from session memory.

The Golden Rule of TryFunctions (MB-820 Exam Essential)

CRITICAL EXAM WARNING: Procedures marked with [TryFunction] (and any procedure called within their scope) CANNOT perform database write operations ( Insert , Modify , Delete , ModifyAll , DeleteAll ) or invoke Commit() .

If any database write operation is attempted inside a TryFunction, the Business Central runtime immediately throws a fatal exception: "The following C/AL functions can be used only to read the database, not to write to it: Insert, Modify, Delete... in a TryFunction."

Correct Use Case: TryFunctions must be used strictly for non-database operations: calling external REST/SOAP APIs, parsing JSON/XML payloads, evaluating complex math, or interacting with .NET/Azure services.