Skip to main content

Error Handling

Aptean Mesh gives you three distinct ways to surface errors from AL to the mobile client. Choosing the right one depends on whether the error is a programming fault, a soft business validation, or a decision the user needs to confirm.


The Three Patterns

Pattern 1 — Error(): Hard stop

Use AL's built-in Error() for unrecoverable faults — missing required data, failed BC operations, unexpected state. The platform catches the exception and shows a system error dialog on the client. The call returns no response data.

// Missing required parameter — programming error, should never happen in production
if State.GetDocumentNo(false) = '' then
Error(MissingDocumentNoErr);

// BC posting failure — unrecoverable
WhseReceiptLine.Get(DocumentNo, LineNo);
if not WhseReceiptLine.Find() then
Error(LineNotFoundErr, DocumentNo, LineNo);

When the client sees this: A generic error dialog with the AL error message. No navigation occurs.


Pattern 2 — State.Command().Alert(): Soft business message

Use Alert for expected business validation failures — lot expired, quantity exceeded, bin not found. The title and message are fully under your control, and you can pair it with haptic feedback.

local procedure ValidateLot(var State: Codeunit MobileRPCState220FDW) Result: JsonObject
begin
if ExpiryDate < WorkDate() then begin
State.Command()
.Alert('Lot Expired',
StrSubstNo('Lot %1 expired on %2. Scan a valid lot.',
LotNo, Localization.FormatDateForDisplay(ExpiryDate)))
.VibrateError();
exit(State.Serialize());
end;

if Qty > OutstandingQty then begin
State.Command()
.Alert('Quantity Too High',
StrSubstNo('Max quantity for this line is %1 %2.', OutstandingQty, UOM))
.VibrateError();
exit(State.Serialize());
end;

// Validation passed — continue
end;

When the client sees this: A titled overlay dialog with your message. The page stays open and the user can retry. Always exit(State.Serialize()) immediately after queuing the alert.


Pattern 3 — State.Command().Confirm(): Ask before acting

Use Confirm when you need the user to acknowledge a consequence before you act. The client shows a dialog; if the user confirms, the client re-calls the action with an extra flag you can read.

// In the AL handler — check if the user has already confirmed
local procedure OnPost(var State: Codeunit MobileRPCState220FDW) Result: JsonObject
begin
// First call: no confirmation yet — ask
if State.GetInput('confirmed', false) = '' then begin
State.Command().Confirm(
'Post Receipt',
StrSubstNo('Post receipt %1 with %2 lines?', DocumentNo, LineCount),
'onPost'); // actionId to call when user taps Confirm
exit(State.Serialize());
end;

// Second call: user confirmed — proceed
PostWhseReceipt(DocumentNo);
State.Command().Navigate('RECEIPT-LIST').VibrateSuccess();
exit(State.Serialize());
end;

The actionId passed to Confirm must match the id of the action in the page contract. When the user confirms, the client re-fires that action. Include "confirmed" in the action's params array so the second call carries it:

{ "id": "onPost", "type": "api", "method": "OnPost", "params": ["confirmed"] }

When the client sees this: A dialog with Confirm / Cancel buttons. Cancel does nothing. Confirm re-calls the action.


Decision Table

SituationPatternMethod
Missing required data, impossible stateHard stopError(...)
Lot expired, bin not found, qty exceededSoft messageState.Command().Alert(title, msg)
Destructive action (post, delete, reset)User decisionState.Command().Confirm(title, msg, actionId)
Posting succeeded — navigate awayNavigationState.Command().Navigate(pageCode).VibrateSuccess()

Common Mistakes

Forgetting exit(State.Serialize())

After queueing an Alert or Confirm, you must return immediately. If you continue executing handler logic after queuing the command, you risk partially mutating state that the user never confirmed.

// ❌ Wrong — continues after Alert
State.Command().Alert('Lot Expired', '...');
PostLine(State); // this still runs!

// ✅ Correct — exits immediately
State.Command().Alert('Lot Expired', '...');
exit(State.Serialize());

Using Error() for expected business conditions

Error() shows a generic system dialog with no title control. For warehouse workers, a message like "Required parameter 'lot' is missing" is confusing. Use Alert for any condition you expect to happen during normal warehouse operations.

Not pairing VibrateError() with error alerts

Haptic feedback is a key accessibility aid for scanner-based workflows. Workers often scan without looking at the screen. Always pair an alert with .VibrateError() so the device vibrates on a rejection.

// ✅ Worker feels the rejection even without looking at the screen
State.Command()
.Alert('Wrong Item', StrSubstNo('Expected %1, scanned %2.', ExpectedItem, ScannedItem))
.VibrateError();
exit(State.Serialize());