npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vishnuprasath28/mx-error-handler

v0.3.2

Published

CLI tool that audits and adds error handling to Java/JS/REST/sub-microflow activities in Mendix microflows via mxcli.

Readme

mx-error-handler

A small command-line tool that sets up error handling on risky activities (Java actions, REST calls, sub-microflow calls, etc.) in your Mendix microflows. Instead of clicking through every microflow in Studio Pro, you run one command and the tool adds a proper error handler with a log message to every activity that still uses the default Rollback.


What's new in 0.3.2

  • mxcli parse errors no longer abort the run. If mxcli rejects the MDL (observed: mxcli's own describe emits strings with unescaped ' — its own round-trip bug), the microflow is skipped with a skipped-parse-error outcome. Parse errors happen before any write, so no rollback is needed. Other microflows still get patched.

What's new in 0.3.1

  • Per-microflow rollback fix. 0.3.0's rollback path compared fingerprints after re-executing the original MDL, but mxcli's describe→exec→describe is non-idempotent for exactly the constructs that put us in the failure path — so the rollback "failed" its own verification and the run escalated to a full-snapshot restore (the old all-or-nothing behavior). 0.3.1 trusts a successful exec as "restored" and leaves the outer snapshot as the final safety net. Now a single risky microflow really is skipped without touching the rest.
  • The post-rollback describe is still saved as after_rollback.mdl inside mx-logs/verify-fail-*/ for debugging.

What's new in 0.3.0

  • Live progress bar in every command. A two-line widget (bar on top, module / microflow underneath) shows which microflow is being worked on — no more silent multi-minute scans on large projects. Non-TTY runs (CI, > redirect) fall back to a periodic heartbeat line so logs stay readable.
  • One bad microflow no longer aborts the whole run. If patch hits an mxcli roundtrip issue on a single microflow, that one microflow is rolled back to its pre-patch state individually and marked skipped-verify-failed in the CSV. The other microflows still get patched. The full-snapshot restore is now a last-resort fallback, only triggered when the per-microflow rollback itself fails.
  • MDL diff dumped on verification failure. When verification flags an mxcli mutation, the pre- and post-patch MDL (plus a reason line) are written to mx-logs/verify-fail-<Module.MF>-<ts>/. Diff the two files to see exactly what mxcli changed — useful for reporting bugs or adding the pattern to the risk-skip list.

What's new in 0.2.0

  • New restore subcommand — roll a project back to any _mxerrhandler_snapshot_* folder if Studio Pro surfaces a problem the in-process verification didn't catch.
  • New cleanup subcommand — list and delete old snapshot folders (interactive, or --yes for CI).
  • patch now always keeps its snapshot. Run cleanup after you've confirmed the project loads in Studio Pro. The old --keep-backup flag is gone — this is now the default behavior.
  • Pre-flight "risky construct" skip removed. Every microflow is attempted; per-microflow verification (Layer 3) is the real safety net.
  • Added safety checks to catch BSON/MDL divergence earlier and abort before a bad write.

One-minute overview

| | Does it change anything? | What it gives you | |---|---|---| | audit | No | An Excel-compatible CSV report saved next to App.mpr, listing every microflow's error-handling state. Exits 1 on broken handlers (CE0011) — perfect for CI. | | patch | Yes | Adds error handlers (Custom with rollback + LOG ERROR message) to activities that use the default Rollback. Always writes a snapshot first; if any patched flow corrupts, the snapshot is restored automatically. | | restore | Yes (undoes a patch) | Copies a snapshot folder back over App.mpr + mprcontents/. Use when Studio Pro reveals a problem that the in-process verification didn't catch. | | cleanup | Yes (deletes snapshot folders) | Lists _mxerrhandler_snapshot_* folders next to the project and deletes them after you confirm the patch is good. |

Think of audit as git status and patch as git commitaudit tells you what's wrong, patch fixes it. restore is your git reset; cleanup is git gc.


Install

npm install -g @vishnuprasath28/mx-error-handler

After install, you can run mx-error-handler from any directory.

Prerequisites

  1. Node.js 18 or later — check with node --version.
  2. mxcli installed — the tool shells out to mxcli to read and modify the .mpr safely. Default Windows path C:\MxCLI\mxcli.exe; on macOS/Linux the mxcli binary must be on PATH. Override with MXCLI=/custom/path/mxcli env var.
  3. Close Studio Pro before running patch. Two programs can't write to the same .mpr at once.

Developing locally (without publishing)

git clone https://github.com/vishnuprasath28/mx-error-handler.git
cd mx-error-handler
npm install        # nothing to install — no external deps — but runs the lifecycle
npm link           # exposes `mx-error-handler` globally from your checkout

Quick start — 3 commands you'll actually use

Run these from inside your Mendix project folder (where App.mpr lives):

See the state of your project:

mx-error-handler audit --all-modules --project ./App.mpr

By default writes a CSV report next to App.mpr AND prints the table in the terminal. Pick one with --output console or --output csv. patch accepts the same flag and writes its own per-microflow report.

Preview what patch would do without writing anything:

mx-error-handler patch --all-modules --dry-run --project ./App.mpr

Actually apply the patch:

mx-error-handler patch --all-modules --project ./App.mpr

Before any write, the tool snapshots App.mpr + mprcontents/. After every patched microflow it re-checks that nothing else changed. If one microflow fails verification, just that microflow is rolled back to its original state and skipped; the rest still get patched. Only if the per-microflow rollback itself fails does the whole run abort and restore from the snapshot. See Safety guarantees below.


Picking which modules to process

You must pick one target for every run:

| Flag | Meaning | |---|---| | --module <name> | Just that one module (e.g. --module Orders). | | --all-modules | Every user module. Marketplace modules (Administration, Atlas_Core, etc.) are skipped automatically. |


Error handling strategies (--error-handling)

Only used by patch. Picks how the error handler block is written:

| Value | What it does | When to use | |---|---|---| | custom-with-rollback (default) | Adds ON ERROR { LOG ERROR... }; — database changes from the failing activity get rolled back, then your log message runs. | Most cases. Safest default. | | custom-without-rollback | Adds ON ERROR WITHOUT ROLLBACK { LOG ERROR... }; — database changes are kept, then your log message runs. | Long-running flows where you want to keep partial progress even if one step fails. | | continue | Adds ON ERROR CONTINUE; — no log, just swallow the error. | Legacy modules where you want the flow to ignore errors silently. No log is emitted, so --log-template is meaningless here. |

Example:

mx-error-handler patch --module Orders --error-handling custom-without-rollback --project ./App.mpr

Custom log messages — mx-error-handler.json

Every patched activity gets a LOG ERROR line. By default it looks like:

<MicroflowName> failed - type: <$latestError/ErrorType>, message: <$latestError/Message>

If your team wants a different format, drop a config file next to App.mpr:

YourMendixProject/
├── App.mpr
├── mx-error-handler.json    ← create this
└── mprcontents/

What the config looks like

{
  "templates": {
    "compact":  "'{microflow}: ' + $latestError/Message",
    "verbose":  "'[ERR] {module}.{microflow} - type: ' + $latestError/ErrorType + ' | msg: ' + $latestError/Message",
    "apiflow":  "'API error in {microflow} at ' + toString([%CurrentDateTime%]) + ' - type: ' + $latestError/ErrorType + ', msg: ' + $latestError/Message"
  },

  "defaultLogTemplate": "verbose",

  "moduleLogTemplates": {
    "Integrations": "apiflow"
  }
}

What each section means:

  • templates — Named log messages. The value is a raw MDL expression that produces a string.
  • defaultLogTemplate — The template used when a module has no specific setting. Value is a template name from templates (or a raw expression).
  • moduleLogTemplates — Override per module. Here, the Integrations module uses apiflow, everything else uses verbose.

What you can use inside a template

| Allowed | Why | |---|---| | 'some text' and + to concatenate | Standard MDL string concat. | | {microflow} | Tool replaces with the microflow name. | | {module} | Tool replaces with the module name. | | $latestError/ErrorType | The error category (e.g. Mendix.Core.Error). Available in every error handler. | | $latestError/Message | The error message text. Available in every error handler. | | toString([%CurrentDateTime%]) | Mendix built-in — timestamp when the error hit. | | $CurrentUser/Name | Logged-in user. |

Not allowed:

| Forbidden | Why | |---|---| | $OrderID, $Customer/Name, etc. | The tool doesn't know which variables exist in each microflow — these only exist inside specific flows. Use --handler for that (see below). |

Template priority order (first match wins)

  1. --log-template flag on the command line.
  2. moduleLogTemplates[<ThisModule>] in the config.
  3. defaultLogTemplate in the config.
  4. Built-in default ('<microflow> failed - type: ... msg: ...').

Using --log-template on the CLI

You can override the config for a single run:

# By name — must match a key under "templates" in the config
mx-error-handler patch --all-modules --log-template apiflow --project ./App.mpr

# By raw expression — must contain $, ', or + (the tool detects it's not a name)
mx-error-handler patch --module Orders \
  --log-template "'HOTFIX: ' + \$latestError/Message" \
  --project ./App.mpr

If you pass a name that isn't defined, the tool errors out immediately instead of emitting broken MDL:

[ERR] Orders: Template reference "apifow" from --log-template is not defined.
       Known templates: compact, verbose, apiflow.

Calling a shared handler microflow (--handler)

If you already have a central error-handler microflow (for example Common.MF_HandleError), tell the tool to call it from every handler body:

mx-error-handler patch --all-modules --handler Common.MF_HandleError --project ./App.mpr

The generated handler becomes:

ON ERROR {
  CALL MICROFLOW Common.MF_HandleError();
  LOG ERROR NODE '<module>' (<template>);
};

You decide what Common.MF_HandleError does — send an email, raise a ticket, call an external API, etc. The tool doesn't care, it just calls it.


What's safe — the tool never clobbers your work

The tool only touches bare error clauses:

| Current state | Action | |---|---| | ON ERROR ROLLBACK; (the Mendix default) | Patched. | | ON ERROR; (broken Custom — CE0011) | Patched. | | ON ERROR { ... }; (hand-tuned handler) | Skipped. | | ON ERROR WITHOUT ROLLBACK { ... }; | Skipped. | | ON ERROR CONTINUE; (you chose to swallow) | Skipped. |

Every microflow that needs patching is attempted. The verification layer (see below) re-describes each one after patching and checks that nothing changed beyond the error handler. If mxcli happened to drop data on the rebuild, that microflow is individually rolled back to its pre-patch state and marked skipped-verify-failed in the CSV — the successful ones stay patched.

Run the tool twice in a row — the second run does nothing new. Safe to wire into CI or a pre-commit hook.


Safety guarantees

Three independent layers protect your project. Each microflow is patched atomically. If one microflow can't be patched cleanly, it's rolled back to its original state individually and the run continues. The full-snapshot restore is only used if that per-microflow rollback itself fails.

Layer 1 — Snapshot before any write

Before patching, the tool copies App.mpr + the entire mprcontents/ folder into _mxerrhandler_snapshot_<timestamp>/ next to your project. Restore is a plain file copy (no SQLite editing, no state-tracking). The snapshot is always kept — including after a successful run — because Studio Pro sometimes surfaces corruption that the in-process verification cannot see. Once you've opened App.mpr and confirmed it loads cleanly, reclaim disk with mx-error-handler cleanup. If something is wrong, roll back with mx-error-handler restore.

Layer 2 — (removed)

Earlier drafts had a pre-flight skip for "risky" constructs. It's been removed — everything gets attempted, and Layer 3 is the real safety net.

Layer 3 — Per-microflow verification

After every mxcli exec, the tool re-describes the microflow and compares its structural fingerprint (error handlers stripped, whitespace normalized) to the pre-patch fingerprint. Any difference outside the ON ERROR clauses is treated as corruption. The tool then:

  1. Dumps the pre- and post-patch MDL to mx-logs/verify-fail-<Module.MF>-<ts>/ so you can diff them.
  2. Attempts a per-microflow rollback by re-executing the original MDL, then re-verifying.
  3. If the rollback succeeds → the microflow is marked skipped-verify-failed and the run continues with the remaining microflows.
  4. If the rollback also fails → the full snapshot is restored and the run aborts.

In short: one bad microflow skips itself; only genuinely broken mxcli state triggers the nuclear option.

Override flags (advanced — defaults are safe)

| Flag | Effect | |---|---| | --no-backup | Skip snapshot + verification. Faster but a failure cannot be auto-reverted. Not recommended. |


Undoing a patch (restore) and reclaiming disk (cleanup)

patch always keeps its snapshot. Two commands manage the lifecycle from there:

Roll back to a snapshot (use when Studio Pro reports a broken model after a patch):

mx-error-handler restore _mxerrhandler_snapshot_2026-04-18T05-44-34 --project ./App.mpr

The snapshot path is the folder printed at the end of the patch run. After restore, the project is bit-for-bit identical to its pre-patch state.

Delete old snapshots (interactive by default):

mx-error-handler cleanup --project ./App.mpr

Lists every _mxerrhandler_snapshot_* folder next to the project, shows total size, and prompts: delete all, keep only the most recent, or cancel. For CI / non-interactive use, pass --yes to delete all without prompting.


Common errors and what they mean

| Error you see | What it means | Fix | |---|---|---| | CE0011 — outgoing sequence flow set as error handler (Studio Pro) | The activity has Custom error handling but no handler flow wired. | Run patch — it completes the handler. | | CE0117 — Error(s) in expression (Studio Pro) | A log message contains invalid MDL — usually because --log-template was passed a name that isn't defined, and the tool wrote the raw text. | Run audit to find the broken flows, fix the template name / expression in the config, run patch again. (Current versions of the tool catch this before writing, so this should no longer happen.) | | Template reference "X" is not defined | You passed --log-template X but X isn't a key under templates in your config. | Check the "Known templates" list in the error message. Fix the spelling or add it to the config. | | mxcli exited N errors | The MDL being sent to mxcli is invalid. Usually a typo in a template expression (missing ', stray character). | Fix the template in the config, re-run. |


Full --help reference

mx-error-handler <audit|patch|restore|cleanup> [options]

Subcommands:
  audit     Report-only. Exits 1 if broken handlers (CE0011) are found.
  patch     Apply error handling to activities using the default Rollback.
            Always creates a safety snapshot; you clean it up with 'cleanup'
            after confirming the project loads in Studio Pro.
  restore   Roll back to a snapshot folder when Studio Pro reveals a patch broke something.
            Usage: mx-error-handler restore <snapshot-path> --project ./App.mpr
  cleanup   List and delete old snapshot folders (interactive, or --yes for CI).

Required:
  --project <path>           Path to the .mpr file.
  --module <name>  OR        Process a single module.
  --all-modules              Process every user module.

Reporting:
  --output <console|csv|both> Pick report format. Default: both.

Patch-only options:
  --error-handling <type>    custom-with-rollback (default) | custom-without-rollback | continue
  --log-template <name|expr> Named template from mx-error-handler.json, or a raw MDL expression.
  --handler <qname>          Call this microflow in the handler body.
  --dry-run                  Preview changes — write nothing.

Safety options (advanced — defaults are safe):
  --no-backup                Skip snapshot + verification. Not recommended.
  --yes                      For 'cleanup': skip the confirmation prompt.

Typical workflow

# 1. See what's currently wrong
mx-error-handler audit --all-modules --project ./App.mpr

# 2. Preview what patch would do
mx-error-handler patch --all-modules --dry-run --project ./App.mpr

# 3. Apply — writes a snapshot and keeps it
mx-error-handler patch --all-modules --project ./App.mpr

# 4. Open App.mpr in Studio Pro and confirm it loads cleanly.

# 5a. All good → reclaim disk
mx-error-handler cleanup --project ./App.mpr

# 5b. Broken  → roll back
mx-error-handler restore <snapshot-path> --project ./App.mpr

Every run also writes a log file to ./mx-logs/run-<timestamp>.log with a full record of what was done.