4.4 Error Handling & Transaction Management

Key Takeaways

  • A Mendix microflow operates within a managed transaction context; staged database changes are committed to disk only when the top-level microflow successfully terminates.
  • Custom with rollback immediately reverts all database operations executed up to the failure point, whereas Custom without rollback preserves staged database changes while routing to an error flow.
  • The $latestError system variable is available only on custom error sequence flows; it is a System.Error object exposing the ErrorType, Message, and Stacktrace attributes for diagnostic inspection.
  • Unhandled exceptions in sub-microflows bubble up to the parent Call microflow activity; if no handler exists in the call hierarchy, the entire transaction rolls back.
  • Using Custom without rollback after a database constraint violation (such as a duplicate unique key) results in an unrecoverable transaction failure because the database engine itself marks the transaction aborted.
Last updated: September 2026

4.4 Error Handling & Transaction Management

Intermediate Exam Focus: Error handling and transaction boundaries are among the most heavily weighted topics on the Mendix Intermediate Developer certification. You must thoroughly understand the four microflow error handling options (Rollback, Custom with rollback, Custom without rollback, and Continue), master the exact behavior of database transactions during exceptions, know how to inspect the $latestError variable, and predict how errors bubble across nested sub-microflows.

In enterprise applications, unexpected runtime failures—such as network connection timeouts during REST calls, database unique constraint violations, or null object pointer exceptions—are inevitable. Without robust error handling and transaction management, failures can leave relational databases in corrupted, partially updated states or crash user sessions without informative feedback.


Microflow Transaction Boundaries and Database Lifecycle

In Mendix, business logic executes inside managed Database Transactions. Understanding how the Mendix Runtime coordinates with the underlying relational database (PostgreSQL, SQL Server, Oracle) is critical for diagnosing system state:

[Microflow Starts] ──> Begins Database Transaction
         │
         ├── [Create / Commit Object A] ──> SQL INSERT Staged in Transaction
         ├── [Change / Commit Object B] ──> SQL UPDATE Staged in Transaction
         │
  <Success?>
   ├── YES ──> [End Event Reached] ──────> SQL COMMIT (Persisted to Disk)
   └── NO  ──> [Unhandled Exception] ───> SQL ROLLBACK (All Changes Aborted)

Savepoints: How Mendix Decides How Far Back to Roll

Mendix implements rollback with savepoints, and knowing where they are placed is what makes error-handling questions answerable:

  • A savepoint is created at the very beginning of the top-level microflow whenever an end user triggers it (for example by clicking a button).
  • An additional savepoint is created immediately before any activity configured with Custom without rollback or Continue.
  • Rollback and Custom with rollback revert to the outermost savepoint — the start of the top-level microflow — which is why a sub-microflow's rollback also wipes out work the parent did before calling it.
  • An error flow ending in an error event re-throws the error to the caller; if the caller has no handler, the runtime unwinds to the outermost savepoint anyway. Ending the error flow with an end event stops the error there and lets the caller continue.

The Lifecycle of a Microflow Transaction:

  1. Transaction Initialization: When a top-level microflow is triggered (e.g., via a button click, scheduled event, or REST endpoint), the runtime requests a database connection from the connection pool and starts a database transaction.
  2. Staged Database Operations: When activities execute Commit Object or Delete Object, the runtime sends SQL INSERT, UPDATE, or DELETE statements to the database. However, these changes are staged within the uncommitted transaction—they are not yet permanent.
  3. Atomic Commit: Only when the top-level microflow reaches an End Event does the runtime issue an SQL COMMIT. All staged changes are atomically written to disk simultaneously.
  4. Automatic Rollback: If an unhandled exception occurs anywhere during microflow execution, the runtime issues an SQL ROLLBACK. Every single database modification made since the transaction started is wiped out, preserving referential integrity.

The Four Error Handling Types in Mendix

Every activity in a microflow can be configured with a specific error handling strategy by right-clicking the activity and selecting Set error handling...:

       [Call REST Service] (Configured with Custom with rollback)
              │
              ├──[Normal Flow]──> [Process Response] ──> [End]
              │
              └──[Error Flow]───> [Log $latestError] ──> [Show User Error] ──> [End]

1. Rollback (The Default Setting)

  • Visual Indicator: None (standard activity appearance).
  • Behavior: If an error occurs, the runtime immediately halts execution, rolls back all database operations in the entire transaction, logs an error stack trace to the server console, and propagates the exception to the client (displaying an unhandled system error popup).
  • Use Case: Default safety mechanism when any failure represents an irrecoverable state where processing must stop immediately.

2. Custom with Rollback

  • Visual Indicator: An orange error badge on the activity and a red outgoing Error sequence flow.
  • Behavior: When an exception occurs on the activity, everything rolls back to the savepoint at the very beginning of the top-level microflow — not merely to the start of the failing sub-microflow — and execution then follows the custom error sequence flow.
  • What survives in the error flow: You can still update the database from the error flow. Mendix documents that custom error handling does not affect objects newly created inside the error flow, so an audit or conflict record created there is kept. What you must not do is try to update an object that was created outside that flow and has just been rolled back: Mendix no longer considers it changed, and the attempt raises an error.
  • In-Memory Reality: Database modifications are reverted, but in-memory attribute values and local variables keep whatever they were set to.
  • Use Case: Critical business flows where an integration or calculation fails, and you must revert all staged database mutations, but gracefully log the incident to an audit entity, send an administrative notification, and present a user-friendly message on the page.

3. Custom without Rollback

  • Visual Indicator: An orange error badge on the activity with a dashed red sequence flow.
  • Behavior: When an exception occurs on the activity:
    1. The runtime DOES NOT roll back database operations. All operations staged prior to the failure remain active in the open transaction.
    2. Execution transitions to the custom error sequence flow.
    3. If the error flow successfully reaches an End Event, all database operations (both before the failure and inside the error flow) are committed together!
  • Critical Risk: If you attempt to use this after an SQL constraint violation (e.g., unique key collision), the underlying database engine marks the entire transaction as aborted; any subsequent attempt to commit will crash.
  • Use Case: Non-destructive fallback scenarios, such as attempting to call a primary external currency exchange API, catching a timeout without discarding staged order objects, and routing to a secondary fallback API.

4. Continue

  • Availability: Offered only on Call microflow activities and loops — you cannot set it on an arbitrary activity such as a Retrieve or a Commit.
  • Behavior: All changes are kept and the microflow continues as if no error had occurred. Nothing is logged and nothing is shown to the end user, which is exactly why it must be a deliberate choice rather than a convenient silencer.
  • Use Case: Batch processing where a failure on a single non-critical item (e.g., sending an optional marketing push notification) should not abort the processing of the remaining 999 records.
Error Handling OptionDB Rollback Occurs?Custom Flow Supported?Transaction State for Downstream StepsTypical Architectural Context
RollbackYes (Full)NoAborted immediatelyDefault failure handling; catastrophic errors
Custom with rollbackYes (Full)Yes (Error Flow)Fresh new transactionGraceful recovery with audit logging and clean UI alert
Custom without rollbackNoYes (Error Flow)Original transaction remains openMulti-provider API fallback; compensation logic
Continue (Call microflow and loops only)NoNo (Continues sequence)UnchangedNon-critical loop actions; optional notifications
Loading diagram...
State Transition Model: Mendix Error Handling Types

Inspecting the $latestError System Variable

When execution enters a custom error sequence flow, the Mendix Runtime automatically injects a specialized system object named $latestError into the local scope.

// Accessing error details inside a Log Message activity:
'Integration failure occurred. Type: ' + $latestError/ErrorType +
' | Message: ' + $latestError/Message

Attributes of the $latestError Variable:

$latestError is an object of type System.Error with exactly three string attributes. Memorise the names, because plausible-sounding alternatives such as Code, ExceptionType, or HttpStatusCode are standard exam distractors:

  • $latestError/ErrorType (String): The Java exception type of the error that occurred (for example com.mendix.systemwideinterfaces.MendixRuntimeException).
  • $latestError/Message (String): The message of the Java exception (for example "Connection refused: connect to https://api.paymentgateway.com").
  • $latestError/Stacktrace (String): The stack trace of the Java exception, detailing the method calls, class names, and line numbers where the exception originated.

Mendix also warns that $latestError should not be returned as the result of a microflow, because that leads to unexpected behaviour downstream.

Operational Rules for $latestError:

  1. Strict Error Flow Scope: $latestError is in scope only on the sequence flow originating from an activity with a Custom error handler. Once the error flow merges back into the main flow or exits, $latestError is no longer accessible.
  2. Production Logging Standards: Always capture $latestError/Message and $latestError/Stacktrace inside a Log Message activity configured with Log Node "Integration" or "Billing" and Level Error.
  3. Security Hygiene: NEVER display $latestError/Stacktrace directly to end users in UI popups or web pages. Stack traces expose underlying Java packages, database schemas, and server internals, presenting an information disclosure vulnerability.

Nested Transactions and Sub-microflow Error Bubbling

In modular applications, microflows frequently call sub-microflows that in turn invoke deeper sub-microflows. Understanding how exceptions bubble through nested execution stacks is essential for predictable transaction governance:

Top-Level: [ACT_Order_Checkout]
             └── Call: [SUB_Payment_ChargeCard]
                          └── Call: [IVK_PaymentGateway_REST] ──> [FAIL!]

The Bubbling Mechanism:

  1. No Error Handler in Sub-microflow:

    • If an exception occurs inside IVK_PaymentGateway_REST and no error handler is configured on that activity, the sub-microflow aborts immediately.
    • The exception bubbles up to the calling activity in SUB_Payment_ChargeCard.
    • If SUB_Payment_ChargeCard has no error handler on the Call Microflow activity, the exception bubbles up to ACT_Order_Checkout.
    • If no handler exists anywhere in the call chain, the top-level transaction rolls back completely.
  2. Handler Configured at Higher Level:

    • If ACT_Order_Checkout has configured Custom with rollback on its Call Microflow (SUB_Payment_ChargeCard) activity, it will intercept the bubbled exception!
    • The top-level microflow rolls back all database changes made across the entire hierarchy and routes execution to its own custom error flow.

The Sub-microflow Rollback Trap

Exam Trap: Consider a scenario where ACT_Order_Checkout creates an invoice and commits it (staged in DB). It then calls SUB_ProcessPayment. Inside SUB_ProcessPayment, an error occurs on a REST call configured with Custom with rollback.

What happens to the invoice created by the parent microflow?

  • Because sub-microflows participate in the same parent database transaction, the sub-microflow's Custom with rollback rolls back the entire transaction—including the invoice created by the parent before the sub-microflow was called!
  • If the sub-microflow handles the error cleanly, logs it, and returns a boolean false back to the parent, the parent microflow resumes execution on its normal flow, completely unaware that its invoice was wiped from the database staging area!

Architectural Solution: When sub-microflows handle errors internally, ensure they return clear status indicators (such as an enumeration or boolean) so caller microflows can branch accordingly.

Test Your Knowledge

A microflow creates a persistable AuditLog object and commits it. Next, it calls a REST service configured with the 'Custom with rollback' error handling option. During execution, the REST service encounters a connection timeout. What is the state of the database transaction and execution flow?

A
B
C
D
Test Your Knowledge

Which system variable is available exclusively on a custom error sequence flow following a failed microflow activity, and which attributes does it expose for diagnostic logging?

A
B
C
D
Test Your Knowledge

A parent microflow stages several database commits and calls a sub-microflow. The sub-microflow encounters an unhandled NullPointerException on an activity that has default (Rollback) error handling. Neither the sub-microflow nor the parent's Call Microflow activity has a custom error handler configured. What occurs?

A
B
C
D